2026-03-03 17:43:04 -05:00
|
|
|
<!--
|
|
|
|
|
Sync Impact Report
|
2026-03-04 16:41:54 -05:00
|
|
|
Version change: 1.1.0 → 1.1.1
|
2026-03-03 17:43:04 -05:00
|
|
|
Modified principles: None
|
2026-03-04 16:41:54 -05:00
|
|
|
Added sections: N/A
|
2026-03-03 17:43:04 -05:00
|
|
|
Modified sections:
|
2026-03-04 16:41:54 -05:00
|
|
|
- Dependency Governance — Removed `github.com/miekg/dns` from
|
|
|
|
|
Currently Approved External Dependencies (replaced by
|
|
|
|
|
`golang.org/x/net/dns/dnsmessage` in feature 001)
|
2026-03-03 17:43:04 -05:00
|
|
|
Removed sections: N/A
|
|
|
|
|
Templates requiring updates:
|
|
|
|
|
- .specify/templates/plan-template.md — ⚠ pending (Constitution Check
|
|
|
|
|
section references "[Gates determined based on constitution file]";
|
|
|
|
|
will be populated when /speckit.plan runs against this constitution)
|
|
|
|
|
- .specify/templates/spec-template.md — ✅ no updates required
|
|
|
|
|
- .specify/templates/tasks-template.md — ✅ no updates required
|
|
|
|
|
Follow-up TODOs: None
|
|
|
|
|
-->
|
|
|
|
|
|
2026-03-04 17:03:30 -05:00
|
|
|
# ekdns Constitution
|
2026-03-03 17:43:04 -05:00
|
|
|
|
|
|
|
|
## Core Principles
|
|
|
|
|
|
|
|
|
|
### I. System File Safety
|
|
|
|
|
|
|
|
|
|
The hosts file is a critical operating system resource. Corruption or
|
|
|
|
|
data loss in this file disables all local name resolution and can render
|
|
|
|
|
a machine unusable without manual intervention.
|
|
|
|
|
|
|
|
|
|
- The tool MUST NOT truncate, zero-out, or partially overwrite the hosts
|
|
|
|
|
file at any point during its operation.
|
|
|
|
|
- All writes to the hosts file MUST use an atomic pattern: write complete
|
|
|
|
|
content to a temporary file in the same directory, then rename over the
|
|
|
|
|
original.
|
|
|
|
|
- A backup of the current hosts file MUST be created before any
|
|
|
|
|
modification is committed.
|
|
|
|
|
- If any step in the write pipeline fails, the original hosts file MUST
|
|
|
|
|
remain unmodified.
|
|
|
|
|
|
|
|
|
|
**Rationale**: This tool exists to solve DNS reliability problems. If it
|
|
|
|
|
introduces a new failure mode — destroying the hosts file — it is worse
|
|
|
|
|
than the problem it solves.
|
|
|
|
|
|
|
|
|
|
### II. Standard Library First
|
|
|
|
|
|
|
|
|
|
The Go standard library MUST be the first choice for all functionality.
|
|
|
|
|
External dependencies introduce supply-chain risk, version conflicts,
|
|
|
|
|
and maintenance burden that are disproportionate for a small,
|
|
|
|
|
single-purpose utility.
|
|
|
|
|
|
|
|
|
|
- All functionality MUST be implemented using the Go standard library
|
|
|
|
|
unless a documented technical justification proves it insufficient.
|
|
|
|
|
- When an external dependency is genuinely required, it MUST come from
|
|
|
|
|
one of the following approved sources:
|
|
|
|
|
- `golang.org/x/*` (official Go extended libraries)
|
|
|
|
|
- `dev.emberkom.com/*` (Emberkom internal libraries)
|
|
|
|
|
- Any other external dependency MUST have a written justification in the
|
|
|
|
|
code review or commit message explaining: (a) what standard library
|
|
|
|
|
alternative was considered, (b) why it was insufficient, and (c) what
|
|
|
|
|
the external dependency provides that the stdlib does not.
|
|
|
|
|
- Dependencies MUST be audited when upgraded to ensure no new transitive
|
|
|
|
|
dependencies from unapproved sources are introduced.
|
|
|
|
|
|
|
|
|
|
**Rationale**: A single-binary CLI tool that modifies a system file must
|
|
|
|
|
have a minimal and auditable dependency tree. Every external package is
|
|
|
|
|
an attack surface and a maintenance liability.
|
|
|
|
|
|
|
|
|
|
### III. Go 1.20 Compatibility
|
|
|
|
|
|
|
|
|
|
This tool MUST compile and run correctly with Go 1.20. This version
|
|
|
|
|
ceiling exists to maintain compatibility with legacy systems that cannot
|
|
|
|
|
run newer Go runtimes.
|
|
|
|
|
|
|
|
|
|
- The `go.mod` file MUST specify `go 1.20` as the language version.
|
|
|
|
|
- No language features, standard library APIs, or dependency versions
|
|
|
|
|
exclusive to Go 1.21 or later are permitted.
|
|
|
|
|
- Build and test pipelines MUST use Go 1.20 as the primary toolchain
|
|
|
|
|
version to catch compatibility issues early.
|
|
|
|
|
- If a dependency releases a version that requires Go 1.21+, the tool
|
|
|
|
|
MUST pin to the last Go 1.20-compatible release of that dependency.
|
|
|
|
|
|
|
|
|
|
**Rationale**: The target deployment environments include older systems
|
|
|
|
|
where upgrading the Go toolchain or OS is not feasible. Pinning the
|
|
|
|
|
version ensures the tool remains deployable everywhere it is needed.
|
|
|
|
|
|
|
|
|
|
### IV. Idiomatic Error Handling
|
|
|
|
|
|
|
|
|
|
Errors MUST flow upward through return values. Functions MUST NOT
|
|
|
|
|
terminate the process, call `os.Exit`, or invoke global exit helpers
|
|
|
|
|
except at the top-level `main` function.
|
|
|
|
|
|
|
|
|
|
- Every function that can fail MUST return an `error` value.
|
|
|
|
|
- Callers MUST inspect returned errors and either handle them, wrap them
|
|
|
|
|
with additional context, or propagate them upward.
|
|
|
|
|
- The `main` function is the only location permitted to call `os.Exit`
|
|
|
|
|
or print a fatal error and terminate.
|
|
|
|
|
- Platform-specific code (build-tagged files) MUST return errors to the
|
|
|
|
|
caller rather than terminating directly.
|
|
|
|
|
- Errors presented to the user MUST include enough context to understand
|
|
|
|
|
what operation failed and why (e.g., file path, hostname, DNS server).
|
|
|
|
|
|
|
|
|
|
**Rationale**: Internal `os.Exit` calls make code untestable, prevent
|
|
|
|
|
cleanup logic from running, and cause execution to continue past error
|
|
|
|
|
points when deferred. Centralizing exit decisions in `main` produces
|
|
|
|
|
predictable, debuggable control flow.
|
|
|
|
|
|
|
|
|
|
### V. Simplicity and Single Purpose
|
|
|
|
|
|
|
|
|
|
This tool does one thing: update the local hosts file with DNS entries
|
|
|
|
|
resolved from a specified DNS server. Every design decision MUST favor
|
|
|
|
|
the simplest approach that satisfies the requirement.
|
|
|
|
|
|
|
|
|
|
- The tool MUST remain a single-binary CLI with no external
|
|
|
|
|
configuration files, services, or daemons.
|
|
|
|
|
- Features MUST be justified by a concrete user need, not speculative
|
|
|
|
|
future use. YAGNI (You Aren't Gonna Need It) applies.
|
|
|
|
|
- Dead code, unused exports, and speculative abstractions MUST be
|
|
|
|
|
removed. If code is not called, it does not belong in the repository.
|
|
|
|
|
- The CLI interface MUST remain straightforward: subcommand + flags.
|
|
|
|
|
No interactive prompts, no TUI, no config file parsing.
|
|
|
|
|
|
|
|
|
|
**Rationale**: Complexity is the enemy of reliability. A tool that
|
|
|
|
|
modifies a critical system file must be small enough to reason about
|
|
|
|
|
completely and audit quickly.
|
|
|
|
|
|
|
|
|
|
### VI. Test-Driven Development
|
|
|
|
|
|
|
|
|
|
All new and refactored code MUST be developed using a test-driven
|
|
|
|
|
development (TDD) approach. Tests are not an afterthought — they are
|
|
|
|
|
the specification that drives implementation.
|
|
|
|
|
|
|
|
|
|
- Tests MUST be written before the implementation code they verify.
|
|
|
|
|
The Red-Green-Refactor cycle is mandatory: write a failing test,
|
|
|
|
|
write the minimum code to make it pass, then refactor.
|
|
|
|
|
- Every exported function and every function with non-trivial logic
|
|
|
|
|
MUST have corresponding test coverage.
|
|
|
|
|
- Functions that interact with external resources (filesystem, DNS,
|
|
|
|
|
network) MUST be designed to accept interfaces or parameters that
|
|
|
|
|
enable testing with fakes, stubs, or in-memory implementations.
|
|
|
|
|
Direct calls to OS-level I/O from business logic are prohibited.
|
|
|
|
|
- Platform-specific code MUST have tests that verify the function
|
|
|
|
|
contract (correct return values, correct error conditions) on each
|
|
|
|
|
supported platform.
|
|
|
|
|
- Test files MUST follow Go conventions: `*_test.go` in the same
|
|
|
|
|
package as the code under test.
|
|
|
|
|
- `go test ./...` MUST pass with zero failures before code is merged.
|
|
|
|
|
|
|
|
|
|
**Rationale**: This tool modifies a critical system file. Untested code
|
|
|
|
|
is untrustworthy code. TDD ensures that every behavior is verified,
|
|
|
|
|
every error path is exercised, and regressions are caught immediately.
|
|
|
|
|
It also enforces the interface-based design required by Principle IV
|
|
|
|
|
(idiomatic error handling) and makes the codebase safe to refactor.
|
|
|
|
|
|
|
|
|
|
## Dependency Governance
|
|
|
|
|
|
|
|
|
|
This section codifies the external dependency policy from Principle II
|
|
|
|
|
into an auditable process.
|
|
|
|
|
|
|
|
|
|
| Source | Status | Condition |
|
|
|
|
|
|--------|--------|-----------|
|
|
|
|
|
| Go standard library | Always permitted | N/A |
|
|
|
|
|
| `golang.org/x/*` | Permitted | Must solve a problem stdlib cannot |
|
|
|
|
|
| `dev.emberkom.com/*` | Permitted | Must solve a problem stdlib cannot |
|
|
|
|
|
| All other sources | Prohibited by default | Requires written justification, code review approval, and an entry in this table |
|
|
|
|
|
|
|
|
|
|
### Currently Approved External Dependencies
|
|
|
|
|
|
2026-03-04 16:41:54 -05:00
|
|
|
None. All external functionality is provided by `golang.org/x/net/dns/dnsmessage` (covered by the `golang.org/x/*` blanket approval above).
|
2026-03-03 17:43:04 -05:00
|
|
|
|
|
|
|
|
## Development Standards
|
|
|
|
|
|
|
|
|
|
- **Formatting**: All Go source files MUST be formatted with `gofmt`.
|
|
|
|
|
No exceptions.
|
|
|
|
|
- **Vet/Lint**: `go vet` MUST pass with zero findings before code is
|
|
|
|
|
merged. Additional linting (e.g., `staticcheck`) is encouraged.
|
|
|
|
|
- **Testing**: All new and refactored code MUST have test coverage
|
|
|
|
|
written before the implementation (TDD). Functions that interact with
|
|
|
|
|
the filesystem or DNS MUST be designed to accept interfaces or
|
|
|
|
|
parameters that allow testing with fakes/stubs. `go test ./...` MUST
|
|
|
|
|
pass with zero failures before merge. See Principle VI for the full
|
|
|
|
|
TDD policy.
|
|
|
|
|
- **Build tags**: Platform-specific code MUST use Go build tags
|
|
|
|
|
(`//go:build windows`, etc.) and MUST implement identical function
|
|
|
|
|
signatures across all supported platforms.
|
|
|
|
|
- **Commit messages**: Follow conventional commit format
|
|
|
|
|
(e.g., `fix:`, `feat:`, `refactor:`, `docs:`).
|
|
|
|
|
|
|
|
|
|
## Governance
|
|
|
|
|
|
|
|
|
|
This constitution is the authoritative source of project standards for
|
2026-03-04 17:03:30 -05:00
|
|
|
ekdns. It supersedes informal conventions, ad-hoc decisions, and
|
2026-03-03 17:43:04 -05:00
|
|
|
prior practices that conflict with its contents.
|
|
|
|
|
|
|
|
|
|
- **Amendment process**: Any change to this constitution MUST be
|
|
|
|
|
documented with a version bump, a rationale for the change, and an
|
|
|
|
|
update to the Sync Impact Report at the top of this file.
|
|
|
|
|
- **Versioning policy**: This constitution follows semantic versioning.
|
|
|
|
|
MAJOR for principle removals or redefinitions, MINOR for new
|
|
|
|
|
principles or materially expanded guidance, PATCH for clarifications
|
|
|
|
|
and non-semantic refinements.
|
|
|
|
|
- **Compliance review**: All pull requests and code reviews MUST verify
|
|
|
|
|
that changes comply with the principles defined here. Violations MUST
|
|
|
|
|
be resolved before merge, or the constitution MUST be amended first.
|
|
|
|
|
- **Dependency audits**: When dependencies are added or upgraded, the
|
|
|
|
|
reviewer MUST verify compliance with Principle II and the Dependency
|
|
|
|
|
Governance table above.
|
|
|
|
|
|
2026-03-04 16:41:54 -05:00
|
|
|
**Version**: 1.1.1 | **Ratified**: 2026-03-03 | **Last Amended**: 2026-03-04
|