# Quickstart: Safety, Reliability & Idiomatic Refactor

**Feature Branch**: `001-safety-reliability-refactor`  
**Date**: 2026-03-03  

## Prerequisites

- **Go 1.20** toolchain installed (must be exactly 1.20.x, not newer)
- Administrator/root privileges (required to write the hosts file)
- Git

## Setup

```bash
# Clone and switch to feature branch
git checkout 001-safety-reliability-refactor

# Verify Go version
go version
# Expected: go version go1.20.x ...

# Download dependencies
go mod download

# Run all tests
go test ./...

# Build
go build -o dns-helper .
```

## Project Structure After Refactor

```
dns-helper/
├── main.go                    # Entry point, CLI parsing, os.Exit
├── resolver/
│   ├── resolver.go            # DNS resolution via golang.org/x/net/dns/dnsmessage
│   └── resolver_test.go
├── hostfile/
│   ├── hostfile.go            # Hosts file read/write (atomic pattern)
│   ├── hostfile_test.go
│   ├── managed.go             # Managed block parsing, add, remove
│   └── managed_test.go
├── platform/
│   ├── platform.go            # Interface definition
│   ├── platform_windows.go    # Windows hosts file path
│   ├── platform_linux.go      # Linux hosts file path
│   ├── platform_darwin.go     # macOS hosts file path
│   └── platform_test.go
├── lockfile/
│   ├── lockfile.go            # Lock file acquisition/release
│   └── lockfile_test.go
├── go.mod                     # go 1.20, golang.org/x/net v0.35.0
└── go.sum
```

## Key Implementation Patterns

### TDD Workflow (Constitution Principle VI)

Every change follows Red-Green-Refactor:

1. **Red**: Write a failing test that specifies the desired behavior.
2. **Green**: Write the minimum code to make the test pass.
3. **Refactor**: Clean up while keeping tests green.

```bash
# Run tests for a specific package
go test ./resolver/
go test ./hostfile/
go test ./lockfile/

# Run all tests
go test ./...
```

### Error Handling (Constitution Principle IV)

All functions return errors. Only `main()` calls `os.Exit()`:

```go
// WRONG — do not do this in any package
func doSomething() {
    if err != nil {
        fmt.Println(err)
        os.Exit(1)  // PROHIBITED outside main()
    }
}

// CORRECT — return errors to caller
func doSomething() error {
    if err != nil {
        return fmt.Errorf("doing something: %w", err)
    }
    return nil
}
```

### Testable Interfaces (Constitution Principle VI)

Functions that interact with filesystem or DNS accept interfaces:

```go
// Production: uses real OS calls
manager := hostfile.NewManager(hostfile.NewOSFileSystem())

// Test: uses in-memory fake
manager := hostfile.NewManager(fakeFS)
```

### Atomic Write Sequence

```
1. Backup: copy hosts → <exe-dir>/hosts.bak.<date>-<rand>
2. Write:  assemble content → temp file (same dir as hosts)
3. Sync:   temp.Sync()
4. Chmod:  match original permissions
5. Close:  temp.Close()
6. Rename: os.Rename(temp, hosts)  [retry on Windows]
7. Clean:  delete backup on success
```

## Usage Examples

```bash
# Add DNS entries
dns-helper add -host myapp.example.com -server 10.0.0.53

# Add multiple hosts
dns-helper add -host host1.example.com,host2.example.com -server dns.internal

# Delete specific host entries
dns-helper delete -host myapp.example.com

# Delete all managed entries
dns-helper delete all
```

## Build for All Platforms

```bash
# Windows
GOOS=windows GOARCH=amd64 go build -o bin/windows/dns-helper.exe .

# Linux
GOOS=linux GOARCH=amd64 go build -o bin/linux/dns-helper .

# macOS
GOOS=darwin GOARCH=amd64 go build -o bin/macos/dns-helper .
```

## Dependency Management

```bash
# After removing miekg/dns and adding dnsmessage usage:
go mod tidy

# Verify no unapproved dependencies
go list -m all
# Should only show: golang.org/x/net, golang.org/x/sys (transitive)
```
