acstack 0.50.4 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +14 -7
  3. package/agents/codex/frontend-verifier.toml +89 -6
  4. package/agents/codex/task-checker.toml +83 -2
  5. package/agents/codex/task-executor.toml +83 -1
  6. package/agents/codex/test-writer.toml +77 -1
  7. package/agents/frontend-verifier.md +13 -6
  8. package/agents/task-checker.md +7 -2
  9. package/agents/task-executor.md +7 -1
  10. package/agents/test-writer.md +1 -1
  11. package/assets/terminal-workspace/config.example.yaml +1 -1
  12. package/assets/terminal-workspace/helpers/acstack-md +12 -4
  13. package/assets/terminal-workspace/helpers/acstack-open +10 -2
  14. package/cli/dist/index.js +7187 -6402
  15. package/cli/dist/index.js.map +4 -4
  16. package/cli/package.json +1 -1
  17. package/docs/config-reference.md +113 -14
  18. package/docs/dev-setups.md +4 -4
  19. package/docs/terminal-workspace.md +1 -1
  20. package/docs/workflows.md +22 -16
  21. package/examples/design-doc/acstack/README.md +273 -0
  22. package/examples/design-doc/acstack/acstack.yaml +4 -0
  23. package/examples/design-doc/acstack/cli.yaml +5 -0
  24. package/examples/design-doc/acstack/design.yaml +39 -0
  25. package/examples/design-doc/acstack/github.yaml +12 -0
  26. package/examples/design-doc/acstack/host.yaml +14 -0
  27. package/examples/design-doc/acstack/journey.md +85 -0
  28. package/examples/design-doc/acstack/publication.md +16 -0
  29. package/examples/design-doc/acstack/review-runtime.yaml +24 -0
  30. package/examples/design-doc/acstack/skills.yaml +22 -0
  31. package/examples/design-doc/acstack/store.yaml +11 -0
  32. package/examples/design-doc/acstack/user.yaml +15 -0
  33. package/examples/design-doc/acstack/viewer.yaml +13 -0
  34. package/hooks/ac-writing-style-reminder.sh +7 -18
  35. package/hooks/communication-standard.mjs +17 -0
  36. package/hooks/communication-standard.sh +6 -0
  37. package/hooks/context-pressure.sh +2 -2
  38. package/hooks/hooks.json +18 -0
  39. package/hooks/lib/communication-standard.mjs +16 -0
  40. package/hooks/project-data.sh +38 -0
  41. package/hooks/session-start-handoff.sh +21 -7
  42. package/hooks/session-start.sh +9 -2
  43. package/orchestrator/AGENTS.md +25 -14
  44. package/output-styles/ac-writing-style.md +75 -276
  45. package/package.json +2 -1
  46. package/pi/agents/frontend-verifier.md +89 -6
  47. package/pi/agents/task-checker.md +83 -2
  48. package/pi/agents/task-executor.md +83 -1
  49. package/pi/agents/test-writer.md +77 -1
  50. package/pi/extension.ts +70 -12
  51. package/profiles/fullstack-python.yaml +1 -1
  52. package/profiles/node-typescript.yaml +1 -1
  53. package/profiles/python.yaml +1 -1
  54. package/skills/archive/SKILL.md +53 -36
  55. package/skills/bootstrap/SKILL.md +6 -6
  56. package/skills/bridge/SKILL-VM.md +11 -2
  57. package/skills/bridge/SKILL-WINDOWS.md +3 -3
  58. package/skills/browser-verify/SKILL.md +14 -5
  59. package/skills/code-review/SKILL.md +8 -2
  60. package/skills/commit/SKILL.md +7 -6
  61. package/skills/compact-and-continue/SKILL.md +9 -8
  62. package/skills/design-doc/SKILL.md +238 -0
  63. package/skills/explore/SKILL.md +1 -1
  64. package/skills/grilling/SKILL.md +4 -4
  65. package/skills/handoff/SKILL.md +4 -4
  66. package/skills/host/SKILL.md +1 -1
  67. package/skills/host/detect-host.sh +2 -2
  68. package/skills/host/notes.md +2 -2
  69. package/skills/host/questions.md +1 -1
  70. package/skills/implement/SKILL.md +20 -13
  71. package/skills/implement/decision-log.md +9 -8
  72. package/skills/implement/design-pass.md +16 -2
  73. package/skills/map/SKILL.md +15 -71
  74. package/skills/map/alignment.md +18 -27
  75. package/skills/map/frontend.md +1 -1
  76. package/skills/map/materialising.md +74 -0
  77. package/skills/map/trackers/files.md +4 -6
  78. package/skills/pre-commit-review/SKILL.md +15 -9
  79. package/skills/pre-commit-review/auto-fix.md +1 -1
  80. package/skills/quick-fix/SKILL.md +1 -1
  81. package/skills/record-context/SKILL.md +6 -6
  82. package/skills/setup/SKILL.md +15 -50
  83. package/skills/setup/browser.md +2 -2
  84. package/skills/setup/first-run.md +19 -8
  85. package/skills/setup/report.md +3 -2
  86. package/skills/setup/row-fixes.md +56 -9
  87. package/skills/sync/SKILL.md +12 -11
  88. package/skills/terminal-workspace/SKILL.md +1 -1
  89. package/skills/test-conventions/SKILL.md +2 -2
  90. package/skills/visual-docs/SKILL.md +69 -235
  91. package/skills/writing/SKILL.md +29 -217
  92. package/skills/writing/examples.md +62 -129
  93. package/docs/adr/0001-ste-writing-standard.md +0 -16
  94. package/docs/adr/0002-version-gate-not-auto-bump.md +0 -35
  95. package/docs/adr/0003-handoff-ack-command.md +0 -19
  96. package/docs/adr/0004-dev-setup-per-host.md +0 -13
  97. package/docs/adr/0005-two-orchestrators-per-host.md +0 -25
  98. package/docs/adr/0006-document-opener-service.md +0 -89
  99. package/docs/adr/0007-lead-check-reads-the-transcript.md +0 -87
  100. package/docs/adr/0008-cli-audits-skill-interviews.md +0 -37
  101. package/docs/adr/0009-verify-the-write-not-the-writer.md +0 -51
  102. package/docs/adr/0010-promote-dev-to-main-by-fast-forward.md +0 -115
  103. package/docs/adr/0011-node-header-is-the-edge-encoding.md +0 -20
  104. package/docs/adr/0012-node-kind-is-a-closed-set-of-five.md +0 -31
  105. package/docs/adr/0013-the-diagram-renderer-is-pure.md +0 -23
  106. package/docs/adr/0014-reading-a-node-hides-its-generated-diagram.md +0 -29
  107. package/docs/adr/0015-a-node-id-links-to-its-issue-through-an-anchor.md +0 -37
  108. package/docs/adr/0016-the-map-root-carries-no-status-of-its-own.md +0 -21
  109. package/docs/adr/0017-call-impeccable-copy-only-its-questions.md +0 -13
  110. package/docs/adr/0018-alignment-packs-use-local-viewers.md +0 -11
  111. package/docs/adr/index.md +0 -18
@@ -1,115 +0,0 @@
1
- # A labelled workflow fast-forwards main to dev, and nobody merges
2
-
3
- ACStack promotes `dev` to `main` by fast-forward. Open a pull request with base
4
- `main` and head `dev`. Review it, then add the `promote-to-main` label.
5
- `.github/workflows/promote.yml` checks six preconditions and moves
6
- `refs/heads/main` to the commit the pull request carries.
7
-
8
- GitHub then closes the pull request as merged on its own. `main` reaches every
9
- commit on `dev`, which is what GitHub reads as merged. The workflow pushes with
10
- `GITHUB_TOKEN`, so no credential sits at rest in this repository.
11
-
12
- GitHub offers no fast-forward merge. Its three options are a merge commit, a
13
- squash, and a rebase. Each one writes a commit to `main` that `dev` can never
14
- contain, and that commit forces a back-merge afterwards.
15
-
16
- Commits `ee41411` and `04602c7` are the last two the old flow cost. The open
17
- question was how to stop a person merging into `main`. `GITHUB_TOKEN` bypasses
18
- nothing, which rules out the usual answer.
19
-
20
- ## Considered options
21
-
22
- A GitHub App can hold a bypass on a ruleset, so an App blocks the Merge button
23
- outright. We rejected it for two reasons. Its private key would sit in a
24
- repository secret and need rotating by hand, and this repository has one person
25
- in it.
26
-
27
- We rejected a fine-grained personal access token for two other reasons. It
28
- expires silently. Its bypass would also come from the owner's admin role, which
29
- leaves the Merge button open to the very person the rule binds.
30
-
31
- We chose `GITHUB_TOKEN`. Nothing sits in a secret, the token expires when the
32
- job ends, and GitHub scopes it to this repository.
33
-
34
- That choice rules out a bypass, so the block comes from somewhere else. It comes
35
- from a required check that no ordinary pull request ever gets: `promotion-gate`.
36
- Only `promote.yml` creates it.
37
-
38
- A pull request into `main` without the label is missing that check and cannot
39
- merge. `enforce_admins` extends that to admins. The workflow posts the check
40
- green immediately before it moves the ref, then flips it to failed if the push
41
- does not land.
42
-
43
- A personal repository could not have taken the App route anyway. The rulesets
44
- API rejects the GitHub Actions integration as a bypass actor. Classic branch
45
- protection rejects a bypass list outright.
46
-
47
- Both errors came from this repository, and `promote.yml` quotes both messages.
48
-
49
- ## Consequences
50
-
51
- `main` stays an ancestor of `dev` by construction. The next promotion therefore
52
- fast-forwards too, and nothing is ever stranded on `main`.
53
-
54
- Three things follow as rules rather than preferences. No merge commit, squash,
55
- or rebase onto `main`. No cherry-pick onto `main`, since a new SHA makes the two
56
- graphs diverge for good.
57
-
58
- No back-merge of `main` into `dev` either. A fast-forward strands nothing there.
59
-
60
- The Merge button works for about a second per promotion. That is the gap between
61
- `promotion-gate` going green and the ref moving, inside a run an admin
62
- triggered. Pressing it there writes a merge commit to `main`, and the
63
- fast-forward then refuses and says so.
64
-
65
- The gate step therefore sits as late in the job as it can. Every new
66
- precondition belongs above it.
67
-
68
- A push made with `GITHUB_TOKEN` starts no workflow runs. `tag-release.yml` would
69
- never fire, and a promotion would tag nothing. `promote.yml` dispatches it
70
- explicitly through `workflow_dispatch`. GitHub documents that event as always
71
- creating a run.
72
-
73
- Nothing enforces that coupling. Add any future workflow that triggers on a push
74
- to `main` to the dispatch step by hand.
75
-
76
- `tag-release.yml` no longer compares `HEAD` against `HEAD~1`. A fast-forward
77
- carries every commit `dev` collected, so `HEAD~1` is the second-newest `dev`
78
- commit rather than `main`'s previous tip.
79
-
80
- Most of those commits leave the version alone, so the old comparison would read
81
- "unchanged" and skip the tag. The workflow now tags whatever version `main`
82
- holds, unless that tag already exists.
83
-
84
- The label that starts a promotion used to sabotage it. `version-gate.yml`
85
- triggers on `labeled` and `unlabeled`, so adding `promote-to-main` started a
86
- fresh `version-gate` run on the same commit.
87
-
88
- That run is pending while the promotion reads the checks and pushes, and branch
89
- protection refuses a push whose required check is pending. Removing and re-adding
90
- the label fired the gate twice more, so the advice for a stuck promotion made it
91
- permanent.
92
-
93
- `version-gate.yml` now skips every label event except `no-bump`. That is the one
94
- label which changes its verdict. A skipped job reports as passing, so the earlier
95
- green run still stands.
96
-
97
- `promote.yml` also waits up to ten minutes on a pending or absent check, rather
98
- than refusing it.
99
-
100
- The close step looks the gate up by name on the commit, not by the id the open
101
- step captured. A `POST` can land while `gh` still exits non-zero on a dropped
102
- response read. Trusting that id would leave the gate green and the pull request
103
- mergeable by hand.
104
-
105
- One hole stays open. A runner killed between the gate opening and the ref moving
106
- leaves `promotion-gate` green with no job left to close it. Close the pull
107
- request, or set that check run to `failure` by hand.
108
-
109
- An admin can still turn branch protection off in the repository settings. No
110
- configuration prevents that on any plan. This decision makes merging into `main`
111
- impossible, not repository administration.
112
-
113
- `promote.yml` names five CI checks by their `name:` values in `ci.yml`,
114
- `tests.yml`, and `version-gate.yml`. Rename a job in one place without the
115
- other, and every promotion blocks. The workflow says so when it happens.
@@ -1,20 +0,0 @@
1
- # The node body header is the authoritative edge encoding on GitHub
2
-
3
- Every map node on the GitHub tracker opens its body with one header line. It names the node's map, its root, its `answers` parent, its `blocked-by` ids, and its short `label`. Every composed query reads its edges from that line.
4
-
5
- The tracker still writes GitHub's native sub-issue and dependency links. Those links drive GitHub's own interface, and no query reads them.
6
-
7
- The header costs one `gh issue list` call to read the whole graph, because `body` is one of the fields that command returns.
8
-
9
- ## Considered options
10
-
11
- - Read the edges from GitHub's native links. Rejected: the parent needs a GraphQL query and the blockers need a REST call, both per issue. A forty-node map would spend eighty calls on every frontier recompute.
12
- - Drop the native links and keep only the header. Rejected: the links render a map inside GitHub's own issue interface. That is half the reason to pick this tracker.
13
- - Give the files backend the same header. Rejected: its frontmatter already holds `answers` and `blocked-by`, and its directory name is the map. A header there would copy data the CLI owns, free to drift from it.
14
-
15
- ## Consequences
16
-
17
- - One edge lives in two places on GitHub. The tracker doc states the dual write as a single step, for adding an edge and for removing one. A write that updates one copy alone leaves the two out of step.
18
- - A degraded remote, meaning one where GitHub's link features are off, now loses only the link interface. Every query keeps working. The tracker needs no second encoding and no per-map choice between them.
19
- - A reader landing on an issue from a notification sees which map it belongs to and what sits above it. The issue title alone never told them.
20
- - The two backends no longer share one body shape. A header line on GitHub, frontmatter on files.
@@ -1,31 +0,0 @@
1
- # A map node's kind is a closed set of five
2
-
3
- A map node carries one `kind`. It is one of `destination`, `notes`, `decision`, `research`, or `work`.
4
-
5
- The CLI enforces the set with a zod enum. It rejects anything else at create, at update, and on reading a stored file. Before this, `kind` was free text that the CLI called advisory only.
6
-
7
- The five split in two. `destination` and `notes` are records rather than questions. `decision`, `research`, and `work` are things still to settle.
8
-
9
- The two records resolve differently. `notes` resolves the moment someone writes it. `destination` is the root, and it carries no status of its own.
10
-
11
- The root's state follows its subtree. It stays open while any node below it still needs work. `archive` resolves it when the map clears.
12
-
13
- Each has one test.
14
-
15
- - `destination` is the root, one per map
16
- - `notes` holds no question, and it binds every other node
17
- - `decision` has two or more defensible answers
18
- - `research` has one findable answer
19
- - `work` ends in a diff
20
-
21
- ## Considered options
22
-
23
- - Keep `kind` free text and let the generated legend list only the kinds a map happens to contain. Rejected: `kind` now picks a node's shape in the map diagram, and an unknown value has no drawing.
24
- - Fix a set of six, to leave one slot spare. Rejected: every candidate sixth landed inside an existing kind. A bug is `work`, a spike is `research`, and a glossary term is a `decision` about what a word means.
25
-
26
- ## Consequences
27
-
28
- - Five kinds map to five distinct mermaid shapes, so shape carries kind and the other channels are free for status, mode, and the frontier.
29
- - Every node must name a kind, and nothing can clear it. A node with no kind has no shape, so the field cannot be optional.
30
- - The enum rejects any map still carrying an older kind such as `grilling` or `task`. That is acceptable, because nodes are transient working state a map throws away at archive.
31
- - `kind` and `mode` will agree most of the time, and the disagreements are the point. A `decision` node marked `afk` draws as a dashed rhombus, which is an agent about to settle something that was the human's.
@@ -1,23 +0,0 @@
1
- # The diagram renderer takes nodes in and never calls gh
2
-
3
- `acstack node diagram` reads nodes and writes mermaid. It reads them from disk for a named map, or as JSON on stdin. It makes no network call and needs no authentication.
4
-
5
- On the GitHub backend the agent runs the pipe itself:
6
-
7
- ```bash
8
- gh issue list --label "map:<name>" --state all --limit 500 \
9
- --json number,title,body,state,stateReason,labels,url \
10
- | acstack node diagram --stdin
11
- ```
12
-
13
- ## Considered options
14
-
15
- - Have the CLI run `gh issue list` itself behind a `--tracker github` flag. Rejected: the invocation would then live in both `cli/src/` and `skills/map/trackers/github.md`, and this repository's own rule is that one fact gets one home. It is also nicer for the agent, which is the whole case for it.
16
- - Give the CLI a real GitHub backend that speaks to the API. Rejected: far larger than this effort needs, and it would put authentication inside a renderer.
17
-
18
- ## Consequences
19
-
20
- - The renderer's tests are JSON fixtures. No subprocess, no network, no token, and 59 tests run in the same suite as everything else.
21
- - Both backends reach one rendering path. One line branches on the backend, and the specification demands it: a node id wraps in an anchor when the node carries a URL.
22
- - The agent runs two commands instead of one. `skills/map/trackers/github.md` states the pipe verbatim, so nobody composes it from memory.
23
- - The CLI gained `readStdin`, because `readFileSync(0, 'utf-8')` fails with EAGAIN when a parent process hands over a non-blocking fd 0. An agent harness does exactly that.
@@ -1,29 +0,0 @@
1
- # Reading a node hides its generated diagram
2
-
3
- `acstack node read` and `acstack node walk` strip generated blocks from their
4
- human-readable output, and `--visuals` puts them back. `--json` always carries
5
- the whole body.
6
-
7
- A generated block repeats what the map already holds. An agent that can call
8
- `acstack node frontier` gets those facts on demand, so a picture of them in
9
- every read spends the context twice.
10
-
11
- ## Considered options
12
-
13
- Keeping the whole body is the honest default. It costs an agent a diagram on
14
- every read of every node. A map that draws one on each parent node makes that
15
- cost grow with the map.
16
-
17
- Stripping every mermaid fence would take the hand-drawn diagrams with it.
18
- Those are the explanation the node exists to give.
19
-
20
- ## Consequences
21
-
22
- Only the markers decide what goes. A hand-drawn diagram never sits inside
23
- them, so the split is exact and needs no heuristic.
24
-
25
- A reader who wants the picture passes `--visuals`. A caller composing
26
- something parses `--json`, which never strips.
27
-
28
- A node body that documents the markers keeps them. A marker inside a fenced
29
- code block is prose about the markers, never a block.
@@ -1,37 +0,0 @@
1
- # A node id links to its issue through an anchor
2
-
3
- A generated diagram wraps each node id in an HTML anchor pointing at its
4
- issue. A reader clicks the id and lands on the node.
5
-
6
- The mermaid `click` directive does the same job and does not work here.
7
- GitHub renders at `securityLevel: strict`, and its Content Security Policy
8
- blocks the `frame-src` that directive needs.
9
-
10
- ## Considered options
11
-
12
- Shipping the id as plain text works in every renderer and costs a reader one
13
- copy and one search per node.
14
-
15
- The `click` directive is the documented way to link a node. GitHub's Content
16
- Security Policy stops it.
17
-
18
- ## Consequences
19
-
20
- GitHub documents none of this behaviour. A community thread reports it
21
- working since March 2024, and GitHub has broken it once already. A second
22
- break renders the label as literal `<a href=...>` text rather than plain
23
- text.
24
-
25
- The anchor wraps the id alone, never the whole label, so a link reads as a
26
- link.
27
-
28
- Its `href` takes single quotes, since the mermaid label is already
29
- double-quoted. Mermaid rewrites anything matching `#<word>;` into a
30
- private sentinel. So a quote inside a url becomes `&apos;` and never the
31
- numeric `&#39;`, and `escapeLabel` turns every `#` a label carries into
32
- `&num;`.
33
-
34
- The GitHub renderer needs `url` in the `gh issue list --json` field list. It
35
- has no other way to build the address, so that field is not optional.
36
-
37
- The files backend draws plain ids. A node on disk has no address to link to.
@@ -1,21 +0,0 @@
1
- # The map root carries no status of its own
2
-
3
- A map's root node has no status of its own. Its state follows its subtree: open while any node below it is open, fog, or claimed, and resolved otherwise.
4
-
5
- The frontier never returns the root. `archive` closes it when the map clears.
6
-
7
- Before this, the map skill created the root as resolved and nothing ever changed it. The field called the destination resolved while eleven nodes below it were still open.
8
-
9
- On GitHub, `gh issue create` opened the root issue and nothing closed it. The two backends disagreed, and the GitHub frontier returned its own root.
10
-
11
- ## Considered options
12
-
13
- - Keep the root resolved at creation, and let the frontier skip it as a resolved node. Rejected: a green root on an open map misreads on every diagram. A closed issue at the top of an open map misreads on GitHub.
14
- - Store the derived status on the root and rewrite it after every resolution. Rejected: every writer would have to recompute the subtree, and one missed write leaves a stale field. Deriving it at read time cannot drift.
15
-
16
- ## Consequences
17
-
18
- - The root is the one node whose stored status means nothing on its own. The diagram prints a count in its place, for example `#229 destination - 11 of 13 open`.
19
- - The frontier has one structural exception: the node with no `answers`. Both backends share it, because the diagram renderer runs the same function over GitHub nodes.
20
- - `archive` gains a step. After its gate passes, it resolves the root, then disposes of the map. Its gate ignores the root, or an open root would fail every map.
21
- - A root closed before this decision stays closed. Nothing reopens history.
@@ -1,13 +0,0 @@
1
- # Call impeccable's command line, and copy only its question sets
2
-
3
- acstack uses impeccable, a third-party design plugin, as an optional design gate. acstack calls five commands through impeccable's documented command-line contract: `detect`, `context`, `audit`, `polish`, and `document`. It copies only impeccable's stable question sets, into the map's frontend branch. It never copies impeccable's files and depends on no other surface.
4
-
5
- This project does not own impeccable, and impeccable moved three major versions in a year.
6
-
7
- ## Considered options
8
-
9
- Copying impeccable into acstack turns every upstream release into a manual port. Naming all 23 commands ties acstack to names that change between versions. Putting the integration inside impeccable is not possible, since this project does not own that repo.
10
-
11
- ## Consequences
12
-
13
- A copied question set can go stale, and a rename of one of the five called commands breaks the gate. The version floor (major 4, warn only) surfaces that without blocking a project, since the gate is optional. Commands that change a design's intent never run unattended; a human picks one in a grill round.
@@ -1,11 +0,0 @@
1
- # Alignment packs use local viewers
2
-
3
- Alignment packs must not depend on a remote viewer or remote script. ACStack can open a generated pack in a local browser, including through a localhost server.
4
-
5
- ## Considered options
6
-
7
- A pinned remote viewer keeps generated files smaller. It also makes review depend on network access and trust in a hosted script.
8
-
9
- ## Consequences
10
-
11
- ACStack must inline or vendor the viewer code it needs. A Herdr-style terminal view can follow later if a clean graph viewer exists.
package/docs/adr/index.md DELETED
@@ -1,18 +0,0 @@
1
- - [0001](0001-ste-writing-standard.md) – One plain-language writing standard based on ASD-STE100
2
- - [0002](0002-version-gate-not-auto-bump.md) – A PR gate enforces the version bump; CI never bumps it
3
- - [0003](0003-handoff-ack-command.md) – Handoff acknowledgement is a CLI command, not a reply
4
- - [0004](0004-dev-setup-per-host.md) – Dev setup is declared per host, not per project
5
- - [0005](0005-two-orchestrators-per-host.md) – Two orchestrators coexist on one host, and a checkout's path names its owner
6
- - [0006](0006-document-opener-service.md) – A document opener service on the laptop, separate from the Playwriter bridge
7
- - [0007](0007-lead-check-reads-the-transcript.md) – A session's own transcript decides lead or child, not the environment
8
- - [0008](0008-cli-audits-skill-interviews.md) – The CLI audits, the skill interviews
9
- - [0009](0009-verify-the-write-not-the-writer.md) – The config writer verifies its result instead of predicting it
10
- - [0010](0010-promote-dev-to-main-by-fast-forward.md) – A labelled workflow fast-forwards main to dev, and nobody merges
11
- - [0011](0011-node-header-is-the-edge-encoding.md) – The node body header is the authoritative edge encoding on GitHub
12
- - [0012](0012-node-kind-is-a-closed-set-of-five.md) – A map node's kind is a closed set of five
13
- - [0013](0013-the-diagram-renderer-is-pure.md) – The diagram renderer takes nodes in and never calls gh
14
- - [0014](0014-reading-a-node-hides-its-generated-diagram.md) – Reading a node hides its generated diagram
15
- - [0015](0015-a-node-id-links-to-its-issue-through-an-anchor.md) – A node id links to its issue through an anchor
16
- - [0016](0016-the-map-root-carries-no-status-of-its-own.md) – The map root carries no status of its own
17
- - [0017](0017-call-impeccable-copy-only-its-questions.md) – Call impeccable's command line, and copy only its question sets
18
- - [0018](0018-alignment-packs-use-local-viewers.md) – Alignment packs use local viewers