SOP: Organize a Development Environment
Purpose
Organize, rationalize, configure, and verify a development environment
so that it supports the user's actual work with minimal unnecessary
complexity and a clear path toward reproducibility and maintenance.
Treat the development environment as a working system rather than a
collection of installed applications. Understand what the developer is
trying to accomplish, inspect what already exists, establish appropriate
conventions, make only justified changes, verify the resulting
capabilities, and document important state.
This SOP is intended to guide sustained, collaborative work. Do not
assume that the task can or should be completed in a single response.
Operating Principles
1. Understand before modifying
Do not begin by installing tools or changing configuration merely
because they are commonly recommended.
First determine:
- what the user is trying to develop;
- which projects are relevant;
- what the current environment contains;
- what is already working;
- what is missing or causing friction;
- which constraints apply;
- what the user considers an acceptable development workflow.
Preserve useful existing configuration unless there is a concrete reason
to change it.
2. Prefer project requirements over generic conventions
A project's declared requirements, lockfiles, build configuration, CI
configuration, and actual behavior take precedence over generic
preferences.
Do not impose a global tool or version when the project already provides
a suitable local or project-specific mechanism.
3. Prefer reproducibility over undocumented global state
Where practical, important versions, dependencies, configuration, and
setup procedures should be discoverable from the project or environment
documentation.
When multiple projects require incompatible versions, manage the
incompatibility rather than forcing an artificial common version.
4. Verify capabilities rather than installations
The presence of a binary or package does not prove that the development
workflow works.
Whenever practical, test the capability that matters:
- a compiler should compile;
- a package manager should resolve dependencies;
- Git should authenticate;
- a project should build;
- tests should run;
- a debugger should attach;
- a service should accept the expected connection;
- an IDE should recognize the project.
5. Retrieve facts that can be measured
Prefer direct inspection and current retrieval over model memory or
assumptions.
Examples:
- inspect installed versions rather than guessing;
- inspect listening ports rather than assuming services are stopped;
- inspect available disk space;
- inspect project manifests;
- inspect current Git configuration;
- query external service state when it matters.
6. Treat secrets as sensitive by default
Never unnecessarily expose credentials, private keys, access tokens,
session cookies, secret environment variables, or other sensitive
material in chat, reports, logs, or generated artifacts.
When inspecting configuration, redact sensitive values. Do not ask the
user to paste secrets when a safer mechanism exists.
7. Make consequential changes deliberately
Before deleting software, modifying authentication, changing network
configuration, migrating data, removing project state, or making other
potentially disruptive changes:
- establish what will be affected;
- determine whether recovery is possible;
- explain the relevant consequence;
- obtain appropriate user approval when the action is not clearly
authorized.
Prefer reversible changes during exploration.
8. Optimize for the user's workflow, not aesthetic purity
A development environment does not need to conform to one universal
toolchain.
A slightly unusual configuration that is understood, stable, and
productive may be preferable to a theoretically cleaner configuration
that disrupts the user's work.
Phase 1: Establish Objectives and Scope
Determine what "organize the development environment" means in this
particular case.
Establish, as applicable:
- primary development activities;
- languages and frameworks;
- projects and repositories;
- operating system and hardware;
- preferred editor or IDE;
- local versus remote development;
- container and virtualization requirements;
- databases and other local services;
- external services and hosting;
- expected development lifecycle;
- performance constraints;
- storage constraints;
- security or organizational requirements;
- whether this is a new setup, cleanup, migration, repair,
optimization, or ongoing maintenance.
Ask follow-up questions when missing information would materially affect
the design.
Do not ask unnecessary questions merely to satisfy a checklist.
Low-impact preferences may be resolved using reasonable defaults and
recorded as assumptions.
Phase 2: Survey the Existing Environment
Build an inventory before making substantial changes.
System
Inspect, as appropriate:
- operating system and version;
- architecture;
- CPU;
- memory;
- storage devices;
- available disk space;
- GPU and relevant drivers;
- shell;
- package managers;
- virtualization support.
Development Toolchains
Identify installed and relevant:
- compilers;
- interpreters;
- language runtimes;
- SDKs;
- build systems;
- debuggers;
- package managers;
- version managers;
- container runtimes;
- virtual machines;
- development CLIs.
Record versions where they materially affect compatibility.
Editors and IDEs
Identify:
- installed editors;
- IDEs;
- language servers;
- formatters;
- linters;
- debugger integrations;
- relevant extensions or plugins;
- remote-development facilities.
Local Services
Identify relevant:
- databases;
- caches;
- message queues;
- web servers;
- object stores;
- development APIs;
- containerized services;
- virtual machines.
Determine whether services are persistent, ephemeral, project-specific,
or shared.
Authentication and Configuration
Inspect the mechanisms used for:
- Git authentication;
- SSH;
- package registries;
- cloud providers;
- external APIs;
- credential helpers;
- environment configuration.
Do not disclose secret values.
Project Inventory
Locate relevant source repositories and determine:
- where projects are stored;
- which are active;
- which are archived;
- which are related;
- which require special toolchains;
- which appear abandoned or obsolete.
Phase 3: Map the Development Topology
Understand where the components of the workflow live.
Model the relationship between:
- host operating system;
- editor or IDE;
- local source repositories;
- language runtimes;
- containers;
- virtual machines;
- databases;
- development services;
- remote development hosts;
- staging systems;
- production systems;
- external SaaS and APIs.
Identify important dependencies and boundaries.
For example:
Developer
|
+-- Host OS
| +-- Editor
| +-- Git
| +-- CLI tools
|
+-- Project environment
| +-- Runtime
| +-- Dependencies
| +-- Application
|
+-- Local services
| +-- Database
| +-- Cache
| +-- Object storage
|
+-- Remote systems
+-- Repository hosting
+-- Staging
+-- Production
Do not assume that every component should run locally. Determine whether
local, containerized, remote, or hosted alternatives are appropriate.
Phase 4: Inspect Project-Defined Requirements
For each significant project, inspect available sources of truth such
as:
- README and setup documentation;
- dependency manifests;
- lockfiles;
- version declarations;
-
.tool-versions;
- language-specific version files;
-
devcontainer.json;
- Dockerfiles;
- Compose files;
- Makefiles;
- task-runner configuration;
- CI configuration;
- environment templates;
- setup scripts;
- build scripts;
- test configuration.
Compare declared requirements with the actual environment.
Identify:
- missing dependencies;
- incompatible versions;
- undocumented dependencies;
- obsolete instructions;
- global dependencies that should be project-local;
- project assumptions that are not currently satisfied.
Where documentation conflicts with actual behavior, investigate the
discrepancy rather than blindly following either one.
Phase 5: Establish Environment Conventions
Where useful, establish conventions for:
- source-code locations;
- personal versus work projects;
- repository naming;
- project configuration;
- shell configuration;
- environment variables;
- caches;
- build artifacts;
- temporary files;
- virtual environments;
- container data;
- local databases;
- generated files.
Do not impose a directory structure merely because it is conventional.
Prefer consistency where it reduces cognitive or operational overhead.
Distinguish clearly between:
- system-managed files;
- user-managed configuration;
- project-managed configuration;
- generated state;
- persistent data;
- disposable caches.
Phase 6: Rationalize Toolchains
Look for:
- duplicate runtimes;
- obsolete SDKs;
- competing package managers;
- multiple installations of the same tool;
- abandoned version managers;
- stale development services;
- unnecessary global dependencies.
For each potentially removable or replaceable component, determine why
it exists before changing it.
Prefer:
- explicit project versions;
- established version-management mechanisms;
- lockfiles;
- isolated environments;
- reproducible setup procedures.
Do not remove a component simply because another tool appears to make it
redundant. Determine whether an existing project depends on it.
Phase 7: Configure Git and Repository Access
Inspect and, where appropriate, establish:
- Git identity;
- default branch behavior;
- credential helpers;
- SSH configuration;
- repository-host authentication;
- commit signing;
- global ignore rules;
- useful aliases;
- repository-specific configuration;
- hooks or automation.
Verify actual access rather than merely checking configuration files.
For example:
git --version
git config --list --show-origin
git remote -v
git fetch --dry-run
ssh -T <appropriate-host>
Adapt commands to the actual provider and environment.
Do not expose private keys or authentication tokens.
Phase 8: Configure the Editor or IDE
Configure only capabilities that support the user's workflow and project
requirements.
Consider:
- language servers;
- formatting;
- linting;
- debugging;
- testing;
- Git integration;
- task execution;
- terminal integration;
- project navigation;
- containers;
- remote development;
- relevant extensions.
Prefer project-defined configuration for formatters, linters, compilers,
and other tooling where available.
Avoid installing large collections of extensions merely because they are
popular.
Phase 9: Establish Runtime and Dependency Management
For each relevant ecosystem, determine how versions and dependencies
should be managed.
Potentially include:
- Python environments;
- Node.js versions;
- Java versions;
- Ruby versions;
- Go toolchains;
- Rust toolchains;
- .NET SDKs;
- C/C++ toolchains;
- CUDA or accelerator toolchains.
Where multiple versions are required:
- identify the projects requiring each version;
- determine an appropriate version-management mechanism;
- associate versions with projects where possible;
- verify that project commands select the expected runtime;
- document exceptional cases.
Phase 10: Establish Local Services
For required databases and infrastructure:
- identify the dependency;
- determine whether it should run natively, in a container, remotely,
or through a hosted service;
- determine persistence requirements;
- configure ports and networking;
- establish initialization procedures;
- establish health checks;
- establish reset or teardown procedures;
- test the application's connection.
Document important dependencies.
Avoid deleting persistent development data without establishing whether
it is disposable.
Phase 11: Manage Configuration and Secrets
Establish a clear distinction between:
- ordinary configuration;
- environment-specific configuration;
- secrets;
- generated state.
Where appropriate:
- create or maintain
.env.example;
- ensure secrets are ignored by version control;
- use credential helpers or secret stores;
- avoid hardcoding credentials;
- inspect Git history when accidental secret exposure is suspected;
- redact sensitive values from reports and diagnostics.
If a secret appears in command output, logs, or a file being inspected,
do not reproduce the secret unnecessarily.
Phase 12: Improve Shell and CLI Ergonomics
Consider, according to the user's preferences:
- shell selection;
- PATH organization;
- command completion;
- aliases;
- directory navigation;
- search tools;
- terminal multiplexers;
- prompt configuration;
- project task shortcuts.
Do not optimize terminal aesthetics at the expense of stability or
portability.
Prefer simple, understandable configuration unless the user benefits
from greater complexity.
Phase 13: Assess Security
Perform a proportionate review of the development environment.
Consider:
- firewall state;
- listening ports;
- exposed development services;
- SSH configuration;
- filesystem permissions;
- container privileges;
- Docker socket access;
- stored credentials;
- outdated runtimes;
- dependency provenance;
- unnecessary background services;
- separation between development and production credentials.
Do not assume that a development machine is safe merely because it is
not a production server.
Do not make disruptive security changes without understanding their
effect on the workflow.
Phase 14: Assess Performance and Resource Usage
Inspect resources that may materially affect development:
- disk usage;
- build caches;
- package caches;
- container images and volumes;
- virtual environments;
- compiler caches;
- language-server memory use;
- background services;
- swap;
- filesystem performance.
Distinguish useful persistent state from disposable accumulation.
On constrained systems, prioritize resource efficiency. On powerful
systems, prioritize productivity unless resource consumption creates a
meaningful operational problem.
Phase 15: Verify the Environment
After changes, perform representative tests.
At minimum, verify applicable capabilities such as:
- required runtimes execute;
- dependencies resolve;
- Git authentication works;
- projects configure successfully;
- projects build;
- tests run;
- development services start;
- applications connect to dependencies;
- debugger integration works where relevant;
- editor tooling recognizes the project;
- expected network resources are reachable.
Record failures rather than silently working around them.
If a failure is caused by an unresolved external dependency, identify
that dependency explicitly.
Phase 16: Establish Reproducibility
Ask:
If this machine disappeared tomorrow, how much of this development
environment could be reconstructed?
Identify:
Reconstructible state
- repositories;
- dependency manifests;
- lockfiles;
- version declarations;
- infrastructure definitions;
- container definitions;
- bootstrap scripts;
- version-controlled configuration.
Difficult-to-reconstruct state
- undocumented manual configuration;
- local databases;
- custom scripts not under version control;
- local certificates;
- machine-specific settings;
- proprietary tooling;
- secrets;
- state stored only on the machine.
Prioritize reducing unnecessary irreproducible state.
Do not store secrets in ordinary source-control artifacts merely to make
reconstruction easier.
Phase 17: Produce Persistent Documentation
Where the work is substantial, create or update an environment manifest.
A useful structure is:
# Development Environment
## Hardware
## Operating System
## Toolchains
## Projects
## Runtime Versions
## Local Services
## External Services
## Editor / IDE
## Authentication
## Configuration
## Reproducibility
## Known Exceptions
## Maintenance Tasks
The document should describe meaningful operational state rather than
reproduce every command executed during setup.
Record important deviations from normal conventions and explain why they
exist.
Decision Guidance
When to ask the user
Ask when:
- the desired workflow is genuinely ambiguous;
- two approaches have materially different tradeoffs;
- an action could destroy or alter valuable state;
- credentials or permissions are required;
- organizational policy may apply;
- the user's preferences determine the appropriate architecture;
- the environment cannot be safely inferred from inspection.
When to choose autonomously
Use reasonable defaults when:
- the choice is low impact;
- the choice is easily reversible;
- one option clearly fits the discovered project requirements;
- asking would add friction without improving the outcome.
Record meaningful assumptions so they can be revisited.
When to research externally
Retrieve current information when:
- software versions or compatibility matter;
- a provider or service's current capabilities matter;
- pricing, licensing, or availability matters;
- official documentation is required;
- security advisories may affect the decision;
- the environment depends on a changing external service.
Do not select a vendor merely because it is familiar to the agent. When
choosing among providers, identify viable categories and compare
relevant options against the user's requirements, including cost,
regulation, accessibility, compatibility, support, and operational
burden.
Quality Standards
A well-organized development environment should, as applicable:
- support the user's actual projects;
- have its important dependencies understood;
- avoid unnecessary duplication;
- use appropriate project-specific version management;
- keep secrets protected;
- have important services identifiable;
- have critical capabilities verified;
- minimize unexplained machine-specific state;
- document important exceptions;
- provide a reasonable path toward reconstruction;
- avoid unnecessary complexity;
- remain understandable to its owner.
Do not consider the task complete merely because the requested tools
have been installed.
Completion Review
Before declaring the work complete, review the environment against this
SOP.
Identify:
- requirements that remain unmet;
- assumptions that have not been verified;
- stale or uncertain information;
- unexplained configuration;
- duplicated or obsolete tooling;
- security concerns;
- unreproducible state;
- failed verification steps;
- follow-up maintenance tasks.
Correct issues where practical.
If an issue cannot safely or reasonably be corrected, surface it
explicitly to the user.
The final result should distinguish between:
- verified working;
- configured but not fully verified;
- known limitation;
- requires user decision;
- requires external action.
Maintenance
A development environment is not static.
When this SOP is used for subsequent maintenance, begin with the
existing environment manifest and current inspection rather than
rebuilding the model from scratch.
Periodically reassess:
- obsolete runtimes;
- dependency drift;
- disk consumption;
- abandoned projects;
- stale services;
- authentication configuration;
- security updates;
- reproducibility;
- undocumented changes.
Do not perform cleanup solely because something is old. Determine
whether it is still useful first.