AI · Article 10 of 72 · Part 3

Search First, Build Second

Create a capability-first search sequence and evidence record for build-versus-reuse discovery.

Define the requirement before choosing a dependency. Specify required behavior. Then Search existing options. Then Inspect license and risks. Then Test fit in isolation.
Keep the evaluation record with the component; a popular repository can still be unsuitable.

New code begins accumulating obligations the moment someone depends on it. It needs review, tests, updates, documentation, and a person who can explain what happens when it fails.

Before accepting those obligations, search for a mechanism that already performs the required job. The result may be an existing setting, a package, a service, a documented workflow, or code the team already owns. A search can also establish that new development is justified.

This chapter of The AI Software Factory, in the SalarsNet AI section, asks how to make reuse a disciplined decision rather than an excuse to assemble unfamiliar software quickly. The proposed workflow has not been tested as a comparative productivity experiment.

Its central rule is practical: define the job, inspect plausible existing mechanisms, and compare their full obligations before writing another implementation.

Define the capability before searching

A vague requirement produces a vague search. “Need an inventory system” can lead to large platforms that solve many tasks while obscuring the one that matters.

Write a small contract for the capability. What input arrives? What output is required? Which transformations are allowed? What conditions require a stop or human review? Where will the result run? Which data must remain protected?

For a hypothetical supplier-file converter, the contract might accept specified tabular inputs, preserve original identifiers, apply an approved mapping, flag missing fields, and produce an inspectable output. It might exclude automatic live-system import.

That contract supplies a basis for comparison. A tool supporting the input format but silently guessing ambiguous identifiers does not satisfy it. A package that performs the transformation but cannot run in the intended environment may still be useful behind an adapter, or may be unsuitable.

The concierge chapter explains how manual delivery can reveal the contract. Reuse search should use those observed requirements when available instead of inventing a larger architecture.

Search your own system first

A team can already own a capability under a different name. A reporting script may parse the needed file. An intake workflow may validate identifiers. A shared service may already manage permissions.

Inspect actual behavior and ownership before reusing it. Internal code is not automatically documented, secure, or suitable for a new customer context. A script built for trusted input may fail when exposed to arbitrary uploads.

Ask who maintains it, what tests cover it, where it is deployed, and which assumptions it makes. If the creator is the only person who understands the mechanism, reuse needs a handoff and a clearer contract.

An internal capability can be extracted behind a narrow interface rather than copied into another application. The interface can preserve ownership and make later updates visible. Copying may be reasonable for a small isolated case, but the resulting copies need an update plan.

The search should also include present product settings and integrations. A customer may already own a tool with the required feature. Configuration or training can be a better first response than adding a new subscription.

Compare mechanisms at different levels

Existing solutions can solve the whole job or only part of it. A hosted service may provide a complete workflow. A package may provide parsing. A command-line utility may provide conversion. A documented manual process may provide a reliable baseline.

Do not force every candidate into the same category. Compare what each supplies and what work remains. A cheap parser can be useful while leaving validation, permissions, output review, and support entirely to the team.

A complete service can reduce implementation work while introducing cost, data-processing, availability, and exit dependencies. A local package can provide more control while requiring the team to operate it responsibly.

A manual method can remain appropriate when the task is rare or highly ambiguous. Automation becomes useful when its benefits exceed the additional obligations under the actual conditions.

The comparison should answer the contract, not reward the largest feature list. Extra capabilities can increase configuration and attack surface without helping the chosen task. They can also be valuable if a verified adjacent requirement needs them. Keep the reason explicit.

Inspect the authoritative source

Search results and summaries identify leads. Read the current documentation, repository, license, and relevant examples before relying on a candidate.

Confirm what is supported rather than extrapolating from a demonstration. A tool that parses one file type may not preserve all the fields your workflow needs. A sample using harmless public data may say little about handling confidential inputs.

Record the version and inspection date. A recommendation tied to a particular release can become inaccurate after an API or dependency change. A stable contract can outlive the chosen implementation if its evidence is preserved separately.

GitHub’s dependency graph summarizes supported manifest and lock-file dependencies, including version, license information, and known vulnerability information where available. It is useful inventory evidence, not proof that every dependency or risk has been discovered. Dependency graph.

Use automated inventory as a starting point and inspect consequential dependencies directly. A package can bring transitive components, build scripts, and separately licensed assets whose obligations matter to the product.

Do not confuse visibility with permission

Public code is easy to inspect. Permission to reuse it depends on its license and the relevant circumstances.

GitHub explains that without a license, default copyright restrictions apply, while its platform terms permit viewing and forking public repositories. Those platform actions are not a general grant for unrestricted commercial reuse. Licensing a repository.

Read the actual license and preserve required notices. Check dependencies and assets separately where needed. A repository’s detected license label can be incomplete or fail to capture multiple licenses.

The commercial licensing chapter examines the main distinctions. For search, the practical gate is that unclear rights remain unresolved; a promising implementation does not erase the need to establish permissible use.

Avoid copying code from a discussion or snippet without understanding its origin and terms. The smallest copied function can still create an obligation or provenance problem. A model generating similar code does not establish that the result is original or cleared for use.

Evaluate the total adaptation burden

A candidate rarely fits perfectly. Estimate the work required to adapt inputs, integrate outputs, configure permissions, handle errors, test important cases, and support customers.

Some adaptation is healthy: a narrow adapter can protect the product from an external API and enforce its own contract. Other adaptation can reveal that the candidate’s assumptions conflict with the task.

For the hypothetical converter, a parser may return values without preserving formatting or source-row identity. If the product needs traceable output, the adapter must preserve that connection. A library that guesses types can convert identifiers into numbers and remove leading zeros. The team should test that behavior with harmless examples before adoption.

The example describes plausible failure modes to investigate, not a finding about a particular package. Its point is that basic capability and task correctness are different questions.

Record adaptation work beside the candidate’s advertised features. An existing tool can save time, but the savings depend on the work it actually replaces and the obligations it introduces.

Run a small fit check before integrating

Choose representative inputs from the contract and define expected outputs independently. Include a normal case, a difficult permitted case, and an input that should be rejected or flagged.

For a file converter, tests might check identifier preservation, missing required columns, duplicate rows, and ambiguous mappings. The cases should follow actual requirements rather than mirror the candidate’s demonstration.

Use an isolated environment with harmless data and limited access. Inspect installation and execution behavior appropriate to the candidate. Do not give an unfamiliar package production credentials just because the installation instructions suggest convenience.

Record the candidate version, environment, inputs, commands, outputs, and observed failures. If no execution occurs, describe the decision as documentation inspection rather than tested compatibility.

A proposed fit check establishes behavior only under its cases. Broader reliability and production readiness require additional work. Keep later evaluation cases outside adaptation where transfer matters; otherwise the team can tune the wrapper to a small set and mistake that fit for generality.

No fit check was executed for a specific package in this article. The method is a proposal requiring real candidate identities and test artifacts.

Inspect failure behavior, not only successful output

A component’s failure model becomes part of the product. Does it stop with a clear error, return partial output, retry automatically, or silently substitute a default? Each behavior affects the customer’s task and the wrapper the team must build.

For a hypothetical converter, partial output might be useful if unresolved rows are identified and the customer can review them. The same partial output is dangerous if it appears complete and enters a live system without inspection. The product contract determines which behavior is acceptable.

Check whether failures can be reproduced with the information the component provides. A generic error message may leave support unable to distinguish a missing field from a malformed input. An excessively detailed message can expose private data. The team needs an operational record that explains the condition without collecting unnecessary content.

Also examine resource limits. A mechanism that works on a tiny example may become slow or memory-intensive on permitted larger inputs. Define a reasonable supported boundary and reject inputs outside it clearly. Do not infer unlimited capacity from one successful demonstration.

If the component calls an external service, understand what happens during interruption. A timeout can leave the product uncertain whether an operation completed. Retrying without a clear contract can duplicate work or effects. A read-only transformation and a write to a live system require different controls.

These checks can change the reuse decision even when the successful output is correct. They reveal whether the team can explain, support, and safely recover the task under ordinary adverse conditions. A useful component helps with those obligations or leaves a narrow enough gap that the product can handle them deliberately.

Compare the cost of reuse with the cost of ownership

A reuse decision should include acquisition, adaptation, operation, updates, support, and exit. New development should include design, implementation, review, tests, documentation, maintenance, and the risk of unfamiliar edge cases.

Use the same task scope on both sides. Comparing a complete hosted service with a quick custom happy-path script exaggerates the appeal of building. Comparing a large platform’s configuration with a tiny package exaggerates the appeal of the package if the remaining product obligations are omitted.

A hypothetical comparison could estimate eight hours adapting a known package versus twenty hours creating a narrow implementation. The package might then require additional update review, while the custom implementation requires its own ongoing maintenance. These are illustrative possibilities, not measured effort or universal ratios.

Use ranges when the work is uncertain. Identify the assumption most likely to reverse the decision. If the package’s behavior under a required input is unknown, a small fit check may be more useful than refining the cost spreadsheet.

The choice should remain explainable when estimates change. Reuse is a means of delivering the contract, not a principle that must win every comparison.

Preserve an exit path

A dependency can become unavailable, change terms, or stop fitting the product. An exit path reduces the cost of responding.

Keep your data in a form you can understand and export. Isolate external behavior behind a narrow interface where practical. Preserve the task’s expected outcomes and test cases separately from the chosen implementation.

An adapter does not remove all switching cost. The replacement may interpret inputs differently, use a different failure model, or require a data migration. The interface helps make those differences explicit.

Document what a replacement would need to satisfy. If the team cannot describe the dependency’s job without its product name, the product may be too entangled to change safely.

The fork/package/build chapter examines ownership choices. Search should identify those choices early enough that the team does not inherit a fork accidentally while believing it installed an ordinary package.

Record the reuse decision once

For an accepted component, record its origin, version, license, tested capability, limitations, owner, integration boundary, update policy, and replacement considerations.

A small component catalog can make that record available to the next app. The catalog should preserve evidence rather than award an indefinite approved label. A component tested for one task may need additional evaluation for another.

Record rejected candidates too when the reason is likely to matter later. “Does not preserve source identifiers under tested inputs” is more useful than “not suitable.” Another developer can revisit the conclusion after a release changes the behavior.

Avoid building a new database merely to store a handful of decisions. Existing repository documentation can support a useful catalog if it has clear ownership and review dates.

The decision record helps a team benefit from search more than once. Without it, every app repeats the same investigation or quietly adopts a different dependency for the same job.

Know when new code is justified

New development can be appropriate when existing mechanisms fail a required contract, introduce unacceptable obligations, or make adaptation more costly than a focused implementation.

The justification should be specific. “We want control” becomes useful when it names the behavior or dependency the team needs to control. “Existing tools are bloated” becomes useful when it identifies configuration, cost, or failure consequences relevant to the task.

Build the smallest mechanism that satisfies the contract, preserving the same review and fit-check discipline applied to reuse. Custom code is not automatically safer or easier to maintain because the team wrote it.

If the new capability may be shared, document its inputs and outputs before generalizing it. A function that works for one app can become a reusable component after its assumptions and ownership are clear.

Search has succeeded even when the decision is to build. It provides a record of alternatives, required behavior, and obligations that makes the new implementation more focused.

What Would We Do at Salars?

A proposed Salars reuse pass would begin with the actual capability contract for one software candidate. The team would search existing Salars code and product settings, then inspect a few relevant external mechanisms.

Each plausible candidate would receive a short record of fit, origin, license, dependencies, adaptation, operating burden, and exit. Consequential behavior would be checked with harmless representative inputs before integration. No production access would be granted merely to make a demonstration convenient.

The chosen mechanism would be recorded in the existing repository documentation with an owner and review trigger. A rejected candidate’s specific failure would remain available for later reconsideration.

If new code were justified, the team would preserve the same contract and evaluation cases. This article asserts no completed package test, time saving, or accepted Salars dependency.

Searching first is worthwhile because it changes what the team builds and what it agrees to maintain. The result should be a smaller, clearer obligation that still delivers the customer’s task.

Sources

Sources inspected October 7, 2026. Reuse workflow, fit checks, effort estimates, and Salars application are proposed or hypothetical. No specific component was executed or cleared for commercial use in this article.

Discussion

What would you add or question? Add your comment below. A human reviews it before publication.

Loading comments…

Join the discussion

Comments are public after approval. Please do not include links, email addresses, or private information. For one short AI reply, address @AIGuide in your comment or reply to its opening comment. Cloudflare verifies submissions to limit spam. Read our community guidelines.

The wider community forum is also open: Browse article discussions in the forum · Forum home