Development notes
Read the repository before inventing files, APIs, or features
How to trace requirements, definitions, call sites, and output before an AI-assisted change, using this site’s Button and work page. When evidence is missing, narrow the claim rather than invent a plausible implementation.
- AI collaboration
- Code investigation
- Development workflow
- Change scope
A request to “make the buttons consistent” can quickly suggest a BaseButton, new props, and a few pages to replace. But this site already has a Button, with its own element selection, variants, and prop types. Inventing another one could simply split the same responsibility across two implementations.
AI can produce plausible code quickly. When changing an existing project, plausibility is not enough. Files, interfaces, and features need to fit the repository as it actually exists. Otherwise, the proposal is a solution for a different project.
I start by identifying the observable result the requirement refers to, then trace what currently owns it. Only after finding the definitions and their uses do I decide whether anything new is needed.
Connect the requirement to an actual use first
“Consistent buttons” could mean matching colors and spacing, correct HTML semantics, or matching interaction behavior. These are examples of how to unpack a requirement, not another button incident on this site.
For consistent appearance, start with the shared component and tokens. If a link cannot open in a new tab, inspect the rendered element and href. If an avatar control does nothing, continue into its events and dialog. Three controls looking like buttons does not mean they should all perform the same kind of action.
The Demo link on this site’s project cards uses the local Button with as="a". The avatar enlargement control on the about page also uses Button, but it performs an action. They share part of their presentation; each use still owns its behavior.
The article on button semantics explains how to choose the element. The point here is the order of investigation: find both uses, then see how the shared component supports them. Do not infer the requirement from the component’s name.
Trace definitions and references, not familiar names
This site exports its local .astro Button through a directory entry point. The component defines its accepted props and variants, then uses cn to merge classes. The definition of cn leads to the packages it actually uses.
Following that chain answers questions that matter to a change:
- Which output elements the component already supports, so there is no need to invent those options again.
- How a variant changes appearance, separately from the choice of element.
- How
classis merged and which helper processes a caller’s adjustments. - Which pages might also be affected by a change to a default.
Those answers require reading the current definitions and references. They cannot be inferred from className, to, or asChild used in another project. An API being common in another component library does not make it available here.
Read the manifest too. When an example imports a package, first confirm that it is installed and that its version and the project’s contract fit the intended use. Do not paste a familiar import and leave the user to discover the missing dependency.
A file is not a requirement, and a name is not behavior
This site’s rebuild already documented one example: the old project contained a technology-filter component, but tracing the available entry points did not establish that those controls were mounted. The rebuild preserved the actual project-category switch rather than turning every leftover implementation into a new feature.
The article on investigating old components records that entry-point trace. It asks whether a file can count as a feature of the original site. For an AI-assisted change, another boundary matters: even a sensible new control is not automatically authorized.
The current work page has links to #development and #design. Its script uses the hash to switch sections and updates aria-current. A change to that behavior should follow this actual path, rather than begin by creating another global filter state.
When the code structure comes from guesswork, AI may expand a small request into new state, events, and controls, then write more code to solve the problems it introduced. Inspecting existing responsibilities helps keep the proposal within scope from the start. This is a working method, not an experimental claim about a measured reduction in error rates.
Distinguish “does not exist” from “not found yet”
A search with no matches initially establishes only that this search did not find the target. The name may differ, or the connection may go through an export entry point, a data file, or a dynamic source. Claiming that a capability does not exist requires a more complete investigation.
I return to the page entry point and its imports, then follow components, data, and scripts. If the requirement concerns visible behavior, I also check the actual output. If it involves an API, login, or an external service, corresponding execution evidence and authorization are needed too. Frontend names alone cannot establish the conclusion.
When the repository or external environment is unavailable, label the proposal as an assumption and identify the missing information. For example: “I have not found an existing submission flow; we need to confirm whether a backend interface already exists.” This is a communication example, not a form or API added to this site.
Assumptions can support a discussion of options. They must not masquerade as existing function signatures, and a convincing-looking successful response must never be invented to fill the gap.
Before editing, explain where the change will fit
Not every small change needs a full architecture report. A short, checkable explanation is more useful: what currently owns the responsibility, which contract will change, and which uses must remain intact.
For Button, a change only to shared appearance should first preserve the existing link and action elements. A change to the type default requires checking whether callers depend on the existing behavior. These changes have different effects; “make the buttons consistent” cannot serve as the entire acceptance criterion for both.
After editing, check the actual result, not just the existence of a new file. Types, builds, HTML, and browser operations each have their own scope. The article on builds and completion boundaries explains that verification split.
This order still leaves room for new features. If the current structure genuinely cannot meet the requirement, add what is needed after confirming the gap and authorization. There is no reason to force reuse merely to touch fewer files. Reading the repository gives a new design a basis; it does not mean the architecture can never change.
Scope of this record
This article draws on this site’s current Button definition and uses, class-merging helper, work page, and published account of the rebuild investigation. The button requirements, API gap, and quoted communication are explanatory examples, not new incidents, services, or executed requests. No model capabilities were compared, and development efficiency was not measured.
I want each change to explain why it belongs where it does. When evidence is missing, narrowing the conclusion or obtaining the necessary information is more useful than writing another complete implementation that does not belong to this project.