Skip to content

Positioning

No name-by-name comparison against competing tools, only named standards

Id: 6f5393b2-4bf6-419e-a52e-089ad7ebd33a Type: decision Status: active Evidence: confirmed

README's and llms.txt's "Related work" don't compare Keep the Why against specific competing tools or skills by name (git-why, Agent Decision Records, Addy Osmani's documentation-and-adrs skill, and similar were removed). What stays named: Architecture Decision Records and the AGENTS.md standard — genuine open standards/conventions this project builds alongside, not competitors. The distinguishing description points to docs/philosophy.md and "What this is not" instead of a per-project comparison table.

Reason: started as a fix for a broken link (Agent Decision Records pointed at a generic personal homepage), but the real problem is structural: any name-by-name list of competing tools is incomplete the moment it's written and stale soon after — new tools appear, others go unmaintained, and keeping the list accurate becomes its own maintenance burden unrelated to this project's actual job.

Rejected alternative: keep a maintained comparison table and just fix the broken link. Rejected — doesn't address why it went stale in the first place, and the same drift would recur.

Consequence, caught late: docs/faq.md's "How is this different from git-why, AgDR, or similar projects?" entry was missed when this changed elsewhere (README, llms.txt) — it named both tools and pointed at a README section ("Not a green field") that no longer exists under that name (now "Related work"). Fixed once noticed; recorded here so the next place this wording lives doesn't get missed the same way.

Consequence (2026-09-10, boundary of the rule): the rule covers competitors — tools that also capture rationale. Tools that only consume or display what context/ contains are not a comparison and may be named: the FAQ has entries for DeepWiki and, since 2026-09-10, Obsidian. The Obsidian entry exists because an LLM answer that positioned the two together (correctly: interface versus convention) also claimed the skill runs in the background and that Obsidian's graph shows how decisions relate; neither is true, and without a primary source the next answer inherits the same claims. The entry states the limits (no background process, graph nodes are files not decisions, wikilinks off) rather than the pitch.

Consequence (2026-09-22, second boundary): the rule covers the repository — README, llms.txt, FAQ, the site. A blog article may compare by name, because an article is a dated snapshot by nature and nobody expects it to stay current; the repository is expected to. The maintainer's call, made when two AI-search probes (2026-09-22) showed that outside answers compare Keep the Why by name anyway, and get it wrong until the properties sit side by side. The same probes surfaced three objections that recur across answers — no similarity search, no commit gating, no UI for non-developers — and, as with the Obsidian entry, the FAQ and llms.txt now state each one plainly with its reason, without naming the tools the answers credited. The index skeleton got its name in the specification the same day, because both probes used the blog article's term "deterministic write areas" as if it were the skeleton's official name.

Id: 8e0f497c-f6da-4817-bc5f-4f3a4ecf9cb9 Type: decision Status: active Evidence: confirmed Source: maintainer requests, 2026-09-23/24 (matrix under Evals, then "Why this project is built this way" back to two entries) Revisit when: a section genuinely needs a clickable heading, or the context/ pages stop being served from a file named index.md

Every nav section is a plain heading with its entries beneath: Reference, Examples, "Why this project is built this way" (its two entries: this project's context/ and the live dashboard), and Evals with "Full suite" and "Agent & model matrix", placed between "Why I built this" and Reference.

Reason: Material's navigation.indexes was switched on for one day to make "Evals" a clickable section. Its side effect: the feature treats any index.md inside a section as that section's index page, and the context/ section's page is context/index.md — so that heading became a link and its "Read this project's context/" entry disappeared. Naming the two Evals entries ("Full suite", the 88 cases on Claude Code; "Agent & model matrix", one case across agents) said what the heading could not, and needed no feature.

Rejected alternative: keep navigation.indexes and rename context/index.md's page so it stops being an index. Rejected: the file name is the format's own convention (context/index.md is what the skill writes and the linter checks), and the site should not bend it for a menu.

The site's front page is a landing page in Markdown, not a template and not a raw HTML file

Id: 4e1adc86-c045-45f3-99f6-ce4d04855281 Type: decision Status: active Evidence: confirmed Source: maintainer request, 2026-09-07 ("a landing page as index, link the README from there"); the technical form was the assisting agent's call, accepted Revisit when: the page needs anything CSS can't do (a live element, a carousel, tabs), or Material's hide: front matter stops removing the sidebars

docs/index.md is a Material page with hide: toc (the navigation sidebar stays — without tabs in the header it is the site's only menu, and the first production look had it hidden), its content plain Markdown with <div markdown> blocks (md_in_html, already enabled) and a landing-page section in extra.css built on Material's own color variables. The README is its own page (/readme/), included whole as before.

Reason: the passages on the page that would otherwise drift — the intro paragraph and the "Tested with" line — are included from the README between HTML-comment markers (the latest eval headline was included from docs/evals.md the same way until the maintainer took the numbers off the front page the same day: a release-specific figure next to a timeless claim aged the page with every release), so the page cannot drift from its sources; that is the same one-place rule the README and llms.txt follow. Markdown keeps the page editable like every other doc, keeps light and dark mode for free, and adds nothing to the toolchain.

Consequence (2026-09-08): the README intro is no longer on the landing page at all; the hero carries a three-sentence summary written in docs/index.md itself. Maintainer request ("an abstract short explanation at the top"; a "Description" section holding the full intro below the demo was tried in the same change and dropped the same day — it is on /readme/ anyway, and the page reads leaner without it). A pain line above the summary followed the same day (maintainer's wording: explaining the same thing to your agent for the seventeenth time, new session, another harness, another account; it is missing context/), and was rewritten the same evening to four short statements — the same decision again, new session, no memory of why, the code doesn't carry the reasoning and neither does the changelog (maintainer's wording, the period form chosen over an em-dash form as closer to the rest of the page): the questions and the "seventeenth time" had read as strained, the closing "it is missing context/" pre-empted the summary below it, and the changelog clause ties the pain line back to the hook sentence above it — what the changelog records versus what it cannot carry, the same division from the other side, not a dig; the cross-tool point (another harness, another account) moved out of the pain line on purpose, it lives in the summary's last sentence and on the agent matrix. Rewritten again on 2026-09-09 (maintainer request: cooler, more catchy; the maintainer's sketch was two questions — explaining the same background for the umpteenth time, the agent taking a wrong turn again): three staccato fragments (same question, same wrong turn, same explanation, again), then two short sentences — the agent forgets between sessions; nothing in the repo remembers: not the code, not the changelog, not the docs (first draft had one sentence with "remembers for it"; an external review the same day called the "for it" slightly off, and it went — the bridge sentence answers "nothing remembers" just as well without it; the same review offered "same rejected approach" for "same wrong turn" as closer to the page's register, declined: the one concrete image is what carries the triad, and "rejected alternatives" sits verbatim in the summary three lines below). What changed and why: the old line carried only the maintainer's pain (explaining again); the agent's own failure (the wrong turn, re-suggesting what was rejected) is the stronger pain and was missing. The question form was offered and passed over — it is what had read as strained the first time — and the number ("Xth time") stayed out for the same reason. docs/ joined code and changelog in the list on the maintainer's suggestion: docs say how it works, not why, the same division. The changelog stays named so the line still answers the hook sentence. The bridge into the summary is one added sentence in front of it, "Keep the Why is the part that remembers", answering "nothing remembers" directly; a "because context/ is missing" bridge was rejected again — it would pre-empt the summary and name a directory the first-time reader hasn't met yet. Those two hero passages are the only text on the page not pulled from a source file — a condensation and a hook, not copies, so the one-place rule doesn't apply, but both have to be re-read whenever the README intro or "The problem" changes.

Consequence (2026-09-09, meta description): the site description (site_description in mkdocs.yml, mirrored as the landing page's description front matter, and the text the social-cards plugin prints on share cards) went from 347 characters to under 160. Search engines cut at roughly 160, and the old text broke mid-sentence before its benefit clause; the new one leads with the search terms (project memory, coding agents) and ends on the benefit (nothing rejected is proposed twice). It is the only description on the site — no other page sets its own, so every page inherits it. Consequence (2026-09-09, README order): "The problem" moved from behind Install and Example to directly before "How it works" — the landing page now puts the pain before the explanation, and the README's four concrete costs (re-debate, silent regression, onboarding stall, repeated agent mistakes) were sitting on line 165 behind the install instructions. Only a move, plus the intro's first sentence split into three; the maintainer's condition for touching the README was that it loses no depth — it is the long form, the landing page is the short one.

Consequence (2026-09-09, README images): the README's two raw <img> tags (logo, demo GIF) point at https://keepthewhy.com/assets/... instead of docs/assets/.... On /readme/ the include plugin rewrote the relative path to assets/..., which a directory URL resolves to /readme/assets/... — 404 since #274; MkDocs only corrects Markdown image syntax, not raw HTML. Absolute URLs render on GitHub and on the site alike and keep the GIF's width; Markdown image syntax would have fixed the path but dropped the width.

Consequence (2026-10-01, "Git does the rest"): a section of its own, six cards, between the entry example and the dashboard — maintainer request to name the Git integration on the page (permissions, distribution, reviews, forks, blame); the section form and the sixth card were the assisting agent's proposal, accepted. The "Keep & Share" card had said it in one sentence; expanding that card would have unbalanced the four-card "How it works" row, and the claim deserves the place where a reader has just seen an entry and asks how it reaches the team. The sixth card, Branches, is there because it is the one Git point the format itself was shaped for — the index heading skeleton exists so parallel additions don't collide (entry-format.md). What the section deliberately does not claim: that git blame shows who decided — it shows who committed, which may be the agent's account; the Permissions card says the skill never commits on its own, so the history is a person's. The README's "Keep & Share" paragraph and llms.txt carry the same point in two sentences.

Consequence (2026-10-07, Git hosts): under the six "Git does the rest" cards, a standing row of the six host marks the dashboard's HOSTS table already carries (GitHub, GitLab, Codeberg, Bitbucket, Gitea, Forgejo; Simple Icons, CC0; dashboard.md), one list in the project, not two. Standing, not scrolling: six marks do not fill a strip, and a repeated list reads as filler. Each links to the FAQ answer on hosts, which says which two are tested end to end; the section itself only claims what holds for every host, that context/ needs nothing from it. Maintainer idea; the standing form was the assisting agent's proposal, accepted.

Consequence (2026-10-07, agent strip): the page gained a carousel — the agent logo strip under the hero buttons (entry below) — which the Revisit when line names as something CSS can't do. It can: two copies of the list and a translate by half, on a CSS animation; the script in docs/assets/agents/marquee.js only adds drag-to-scroll and stays out under reduced motion, the way the demo's script already does for its part. The page is still Markdown with HTML blocks; the decision stands.

Rejected alternative: a raw index.html in docs/. Full layout freedom, but it would have to rebuild the header, search, palette toggle and footer itself, and the include mechanism wouldn't reach into it — the facts would be typed in by hand. Also rejected: a custom Jinja page template (template: front matter) — real HTML inside the site chrome, but a second place where layout lives, for a gain (a wider column) the page doesn't need.

The project's own context/ is published on the site through one-line include stubs

Id: f6b2701b-998e-452d-9a37-ee7f5fa5d340 Type: decision Status: superseded Evidence: confirmed Source: how the "Why this project is built this way" nav section has been built since the site exists; the gap noted by Oliver on 2026-09-08 ("are all context files under 'Why this project is built this way'?" — they weren't); the nav change requested on 2026-09-10 (#375, #377) Superseded by: a99c6a7f-7027-4b90-a2e3-b026585fdb5b

Superseded on 2026-09-10 by the build-time hook (next entry); kept for how the section got here.

Every topic file in context/ gets a stub at docs/context/<name>.md holding a single include-markdown line. The stub is the only way a context/ file reaches the site — MkDocs only builds what lives under docs/, and copying the file would create a second place to edit. The nav section "Why this project is built this way" in mkdocs.yml holds one page, titled context/, which is the stub for context/index.md; the index links every topic file, so the site navigation follows the index instead of duplicating it. That stub includes the index with rewrite-relative-urls=false, so the index's relative links (lint.md etc.) resolve to the sibling stubs under docs/context/ rather than to a path outside docs/.

Reason: the nav section used to list every topic file by hand and was always behind — on 2026-09-10 it showed seven of eight files, issue-triage.md had never been added. The index is already the one place that must know every topic file (rule 6 of the skill), so it is the one place the site reads.

Rejected alternative: one nav line per topic file, as before. Rejected because nothing kept the list in sync with context/. Also rejected: making the section heading itself the link to the index (#375) — a top-level page link renders differently from the "Reference" and "Examples" section headings; a section with a single child page (#377) looks like its neighbours.

Consequence: a new topic file is still not on the site until someone adds its stub; nothing checks this. lint.md (2026-09-02) and evals.md (2026-09-05) were both missed for days and added on 2026-09-08. The nav line is no longer a second thing to forget. When adding a topic file, add the stub in the same change.

The project's own context/ is published on the site by a build-time hook, not by stubs

Id: a99c6a7f-7027-4b90-a2e3-b026585fdb5b Type: decision Status: active Evidence: confirmed Source: maintainer request, 2026-09-10 ("mach den mkdocs hook für die stubs"), after the stub gap kept recurring

tools/mkdocs/context_pages.py, wired in through hooks: in mkdocs.yml, turns every context/*.md except README.md, AGENTS.md and CLAUDE.md into the page /context/<name>/ at build time — the file's content, read as-is, as a generated MkDocs page. Nothing exists under docs/context/; a file there fails the build with a message naming the hook, so the stub mechanism cannot quietly come back. The nav section "Why this project is built this way" holds one page, the generated context/index.md; the index links every topic file, so the navigation follows the index instead of duplicating it. Relative links between topic files (lint.md) resolve to sibling pages because the content is not run through the include plugin's URL rewriting — which is also why the index no longer needs a rewrite-relative-urls=false include.

Reason: the stub-per-file mechanism (previous entry) had one manual step that nothing checked, and it was missed three times in a week (lint.md, evals.md, issue-triage.md). A hook has no per-file step: a topic file is on the site the moment it exists. Plain hooks: rather than a plugin because it is a few dozen lines of project-specific glue with nothing to install.

Rejected alternative: keep the stubs and add a CI check that every context/*.md has one. Catches the gap, still asks for the stub. Also rejected: mkdocs-gen-files — a dependency for what hooks: already does in MkDocs 1.6.

Consequence: the docs workflow triggers on tools/mkdocs/** too. context/README.md is deliberately not a page; the index is the section's landing page.

The format has a normative specification file, separate from the guidance that shows it in use

Id: 7feab02f-0de5-48f6-8dfa-20fa233cf0a1 Type: decision Status: active Evidence: confirmed Source: maintainer request, 2026-09-07 ("a spec page that defines the format of context and the config files")

references/specification.md defines what is valid — files, config blocks and fields, the index grammar, the entry grammar, lifecycle, versioning — and is the docs page /specification/. repository-structure.md keeps layout, routing and retrofitting — the examples went with the definitions, so the specification is the one place that shows every file in full; setup.md keeps behavior. Where they disagree, the specification wins.

Reason: the definitions lived between examples in repository-structure.md and between wizard steps in setup.md; a reader who only wanted to know what is valid had to lift the normative sentences out of a narrative, which is what the linter does in code. A convention needs one page that states its rules without telling a story — for tool authors, for reviewers, and for the linter's own contract. Kept inside the skill package rather than as a docs-only page so agents can load it on demand and there is one source; the docs page includes it.

Rejected alternative: a docs-only page stitched from include markers over the existing references. No duplication, but the references would have kept normative and narrative text mixed, and the page would have read as excerpts rather than as a specification.

Keep the Why is the why layer of repo-native project memory, not the memory itself

Id: 92734fc2-5bb5-47e4-ab6e-fad8ee26551f Type: decision Status: active Evidence: confirmed Source: maintainer decision, 2026-09-14, with the publication of the thesis page Revisit when: the thesis page changes its architecture, or Keep the Why grows a layer beyond the why See: https://github.com/oliver-zehentleitner/repo-native-project-memory — 6288e2c2-5d05-405a-8355-3d1c2564adf0 — as of 2026-09-28

Every self-description — landing hero, README intro, Philosophy, Installation, llms.txt, the context/README.md the wizard writes — says that the repository already is the project's memory (README, docs, tests, changelog, history) and that Keep the Why is the layer it was missing: the why. The thesis itself lives on its own page, https://oliver-zehentleitner.github.io/repo-native-project-memory/, by the same author, and Keep the Why links it rather than restating it.

Reason: "Keep the Why is project memory" claimed the whole for a part and put the project in a line of tools that sell a new store; "the why layer of a memory the repository already is" is the smaller and truer claim, and the one the tool can actually back. It also gives the tool a clean role next to everything else in a repository instead of beside it. Keeping the thesis on a separate page keeps this site the practice — releases, measurements, docs — and lets the argument be read, and disagreed with, without adopting any of it.

Rejected alternative: a "Philosophy" section here carrying the thesis. Rejected — the argument holds for other implementations too and should not read as this project's marketing; and a thesis page with its own context/ is a better demonstration than a chapter.

The agent is the installation interface; the skill is the one required part

Id: 2196306f-e2e1-4d07-ab12-41eacd335081 Type: decision Status: active Evidence: confirmed Source: maintainer design discussion, 2026-10-02 — installation trips up developers, experienced ones included, while an agent can be told to pick the right route from the installation page itself Revisit when: agents gain a common way to install a skill from a URL on their own, or the installation page's agent section turns out to send agents down a route that fails See: config-format.md#optional-components-default-to-no-the-agent-knows-them-offers-them-and-sets-them-up-only-on-request — 7889e8b2-d2c3-458d-a19e-10638aca9ded — as of 2026-10-02

README, landing page and installation page lead with one sentence for the agent — install the skill, choosing the route from https://keepthewhy.com/installation/, then set the project up with default settings including autostart — and with the three optional components as one sentence each. The installation page has a section addressed to the agent doing the installing: the order of routes to try, pinned to latest, and what to do when the skill only shows up in a new session. The commands for a human doing it by hand follow below it, unchanged. For the setup half to work as one sentence, the skill treats a request that already gives the answers ("with default settings") as the answer to both wizards.

Reason: the many install routes — skills CLI, gh, asm, five plugin and package mechanisms, the manual copy — are a choice the person should not have to make; the agent knows which of them it supports. The person then talks to one interface for everything: the skill, and each optional component.

Rejected alternative: a single recommended command for everyone, as before. Rejected: one command still leaves the person to know their agent's flags, scope and plugin mechanism, which is where installs failed.

The landing page's demo is a scripted, vendor-neutral simulation, not a recording

Id: d75f1afd-14d7-46c2-8c2d-da4f91c6740d Type: decision Status: active Evidence: confirmed Source: maintainer design discussion, 2026-10-02 (the idea came from pi.dev's in-page agent demo; "simulation, neutral, asking is enough in the third chapter") Revisit when: the README's GIF and the landing page's demo tell visibly different stories, or a reader takes the simulation for a recording See: positioning.md#the-agent-is-the-installation-interface-the-skill-is-the-one-required-part — 2196306f-e2e1-4d07-ab12-41eacd335081 — as of 2026-10-02

The landing page shows a simulated agent session in place of the GIF: a terminal and the project's files side by side, in three chapters — install and set up from the one sentence, learn a reason the code cannot show and record it, a later session that reads it and asks instead of repeating the change. It is a script played by docs/assets/demo/demo.js, plain JavaScript without dependencies, in no particular agent's look. Chapters 2 and 3 are re-enacted from the rejected-change experiment's transcripts, and the caption says it is simulated. With prefers-reduced-motion it is a static transcript; without JavaScript the old GIF stands in. The README keeps its GIF — GitHub runs no script.

Reason: a recording is tied to one agent's interface and to one session's noise, and every change means recording again; Keep the Why works with any agent, and the story is the mechanism, not a vendor's terminal. A script stays text: edited in a pull request, readable by a screen reader, small. Grounding the lines in real transcripts keeps it honest.

Rejected alternative: an asciinema recording of a real session, the way pi.dev does it. Rejected for the reasons above.

Consequence (2026-10-02, maintainer review of the first version): the point is that a fresh agent finds the reason, so the session boundary is a banner of its own ("NEW SESSION · fresh agent, no memory of session 1"); what Keep the Why does is marked apart from the agent's output ("◆ Keep the Why · captured rationale", "… found relevant context") — a marker of the demo, not a line any agent prints; a strip above the terminal tells the story in six words for someone half watching; the agent's lines are cut to cause and effect; the end holds on the second agent's answer instead of moving on; and "simulated coding-agent sessions" stands in the title bar the whole time. Installation stays the first chapter, shortened — how fast it goes is part of the message.

Rejected alternative: a fourth chapter for "asks when unsure". The maintainer's call: the third chapter's closing question already shows it.

The skill explains itself from one reference file, references/help.md

Id: 301d2462-bcb9-4afa-a882-09eb4b12d33e Type: decision Status: active Evidence: confirmed Source: maintainer request, 2026-10-05 ("when people ask the skill how it works, it should know how to explain itself and which interfaces it offers") See: positioning.md#the-agent-is-the-installation-interface-the-skill-is-the-one-required-part — 2196306f-e2e1-4d07-ab12-41eacd335081 — as of 2026-10-05 Revisit when: the sentences on the README and the installation page change, or a new component or mode is added

The skill carries what the README tells a person — what Keep the Why is, which parts are required and which optional, and the sentences that start each mode, setup, an update and each optional component — in references/help.md. SKILL.md names it as a read-before trigger for questions about the skill, and the description names those questions, so the skill is loaded by them.

Reason: the agent is the interface, but the README is not installed with the skill: an agent asked "what can I tell you to do?" knew the modes and the optional components only from scattered rules, and the sentences not at all. One file keeps the answer complete and the sentences identical to the README's.

Rejected alternative: the whole explanation in SKILL.md. Rejected — it is needed only when someone asks, and SKILL.md stays small enough to load on every activation; a read-before trigger is the pattern for that (context/evals.md).

Supported agents are named in plain text, never shown as logos

Id: cd274fee-3191-4ca2-8ab1-999b752d18d4 Type: decision Type: constraint Status: superseded Evidence: confirmed Source: maintainer decision, 2026-10-05, after a check of the vendors' published brand rules Superseded by: 9e2cd363-ee42-4944-9271-ef726c3f1bcb

Superseded on 2026-10-07 by the next entry: the landing page now carries a logo strip. The text lists this entry describes (README, How it works, installation page) stay as they are; what changed is the footing the maintainer accepts for the marks, not the lists. Kept for the brand-rule findings, which still hold.

The README's line above the website link names the agents Keep the Why installs on — Claude Code, Codex, GitHub Copilot, Cursor, OpenClaw, Hermes Agent, Cline, OpenCode, Pi, Antigravity — as plain text, as do the agent lists on the landing page (How it works) and the installation page, where the ones with an install route of their own (the plugins) link it.

Reason: the three best-known names cannot carry a logo: Anthropic allows saying in plain text that a product runs Claude Code and requires written permission for any other use of its names or logos; OpenAI's brand guidelines say not to use its logo without permission; Google requires prior written consent for uses its brand documentation does not cover. Of the others, only some have a mark under an open license, and most publish no rules for third parties at all — which is no permission. A row where the best-known agents are text and the rest logos would point at the gap.

Rejected alternative: logos where a source allows them (OpenClaw and Hermes Agent from their MIT repositories; OpenCode and Pi from Simple Icons, CC0; Cline, Cursor, GitHub Copilot from their brand pages or icon sets), text for the rest. Rejected for the mixed look and the unclear footing of the ones without rules.

The landing page shows supported agents as a logo strip, on the same footing as skills.sh

Id: 9e2cd363-ee42-4944-9271-ef726c3f1bcb Type: decision Status: active Evidence: confirmed Source: maintainer decision, 2026-10-07, prompted by the "Available for these agents" strip on skills.sh Revisit when: a vendor objects or publishes rules that exclude this use, or the skills CLI's agent list changes enough that the strip no longer mirrors it

Between the hero buttons and the license line, the landing page runs a slowly scrolling strip of agent marks: the twenty agents skills.sh shows under "Available for these agents", plus Pi (Simple Icons, CC0). The files live in docs/assets/third-party/agents/ exactly as received, with a README naming owner, origin and the use; the page recolors them at render time with a CSS luminance mask into the link color, hover shows the name, a drag scrolls the strip (docs/assets/agents/marquee.js), and without the script the CSS animation runs alone; under reduced motion the list stands still. Each mark links to its install route on the installation page.

Reason: Keep the Why installs through the skills CLI, so the list skills.sh shows is the one this project inherits — not a selection of its own. The marks are used the way skills.sh uses them: a "works with" strip, one color, no claim of endorsement. That is the same footing, and the maintainer accepts it after seeing it in use there. What this is not: permission. The previous entry's findings stand — Anthropic, OpenAI and Google require written consent for logo use beyond a plain-text mention, most other vendors publish no rules — and the README in the folder exists so a removal request can be met file by file. The previous entry had been the assisting agent's caution, adopted at the time; the reversal is the maintainer's own reading two days later ("if skills.sh may, why not us").

Rejected alternative: name chips in the same strip — no mark at all, nothing to ask anyone; rejected because the maintainer wanted the recognizable logo row. Also rejected: fetching every mark from its vendor's press kit instead of skills.sh — the rights are the same either way (Vercel holds no right in an Anthropic mark), only the provenance paperwork differs. Also rejected: editing the SVGs to recolor them — the files stay byte for byte as received so they can be compared with their origin; the CSS mask does the recoloring.

Consequence (2026-10-07, host row): the Git host row under the "Git does the rest" cards is this strip's twin — same markup, same script, same drag and pace — so the page has one logo-strip behaviour, not two. The one difference is deliberate: six marks do not fill a strip, so where the width holds the row it stands centered and only narrower than that does it scroll; the CSS decides by container width and tells the script through a custom property, rather than the script measuring on its own, so the two never disagree on the mode.