# CLI Contract: dns-helper

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

## Overview

`dns-helper` is a single-binary CLI tool that updates the local hosts file with DNS entries resolved from a user-specified DNS server. It exposes three subcommands: `add`, `delete`, and a usage/help display on invalid input.

## Binary Name

```
dns-helper[.exe]
```

## Global Behavior

- Prints banner on every invocation: `DNSHelper v1.0`, `Copyright (c) 2024 Emberkom LLC`, blank line.
- All error messages are printed to **stderr**.
- Informational output (banner, summaries, warnings) is printed to **stdout**.
- Exit code `0` on full success. Non-zero on any error or partial failure.

---

## Subcommand: `add` (aliases: `a`)

### Synopsis

```
dns-helper add -host <hostnames> -server <dns-server>
```

### Flags

| Flag | Required | Type | Description |
|------|----------|------|-------------|
| `-host` | Yes | string | Comma-separated list of hostnames to resolve and add |
| `-server` | Yes | string | DNS server to use for resolution (hostname or IP) |

### Behavior

1. Validates that both `-host` and `-server` are provided and non-empty.
2. Resolves each hostname against the specified DNS server (follows CNAME chains, deduplicates IPs).
3. Acquires lock file.
4. Reads the current hosts file and parses the managed block.
5. Removes any existing managed entries for the specified hostnames.
6. Adds new entries for all successfully resolved hostnames.
7. Writes the updated hosts file atomically (temp file + rename, with pre-write backup).
8. Releases lock file.
9. Prints summary of changes.

### Output — Success (exit 0)

```
DNSHelper v1.0
Copyright (c) 2024 Emberkom LLC

Added 3 entries for host1.example.com
Added 2 entries for host2.example.com
```

### Output — Partial Failure (exit 1)

```
DNSHelper v1.0
Copyright (c) 2024 Emberkom LLC

Added 3 entries for host1.example.com
Warning: failed to resolve host2.example.com: NXDOMAIN
```

### Output — Validation Error (exit 1)

```
DNSHelper v1.0
Copyright (c) 2024 Emberkom LLC

Error: -host flag is required for the add command
```

### Exit Codes

| Code | Meaning |
|------|---------|
| 0 | All hostnames resolved and written successfully |
| 1 | Any error: validation failure, DNS failure, file write failure, partial resolution |

---

## Subcommand: `delete` (aliases: `d`, `del`)

### Synopsis

```
dns-helper delete -host <hostnames>
dns-helper delete all
```

### Flags

| Flag | Required | Type | Description |
|------|----------|------|-------------|
| `-host` | Yes* | string | Comma-separated list of hostnames to remove (*not required when using `all`) |

### Behavior — Delete Specific Hosts

1. Validates that `-host` is provided and non-empty.
2. Acquires lock file.
3. Reads the current hosts file and parses the managed block.
4. Removes all managed entries matching the specified hostnames.
5. Writes the updated hosts file atomically.
6. Releases lock file.
7. Prints summary.

### Behavior — Delete All

1. Acquires lock file.
2. Reads the current hosts file and parses the managed block.
3. Removes the entire managed block (start marker through end marker).
4. Writes the updated hosts file atomically.
5. Releases lock file.
6. Prints summary.

### Output — Success (exit 0)

```
DNSHelper v1.0
Copyright (c) 2024 Emberkom LLC

Removed 3 entries for host1.example.com
```

### Output — No Entries Found (exit 0)

```
DNSHelper v1.0
Copyright (c) 2024 Emberkom LLC

No managed entries found for host1.example.com
```

### Output — Delete All (exit 0)

```
DNSHelper v1.0
Copyright (c) 2024 Emberkom LLC

Removed all managed entries (5 entries removed)
```

### Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Deletion completed (or no entries to delete) |
| 1 | Error: validation failure, file write failure, corrupt managed block |

---

## Invalid / No Subcommand

### Synopsis

```
dns-helper
dns-helper <invalid-subcommand>
```

### Behavior

1. Prints usage information to stdout.
2. Does **not** modify the hosts file.
3. Exits with code 1.

### Output (exit 1)

```
DNSHelper v1.0
Copyright (c) 2024 Emberkom LLC

This utility will update the local hosts file with DNS entries obtained by the specified DNS server.
Usage: dns-helper [add|delete] -host hostname [-server dns.example.com]
Example:
       dns-helper add -host xyz.acme.com -server dns.example.com
         This will use dns.example.com to find and add all IP addresses for xyz.acme.com to the local hosts file.
       dns-helper delete -host hostname.example.com
         This will delete all entries for hostname.example.com from the local hosts file.
       dns-helper delete all
         This will delete all entries from the local hosts file that were added by this utility.
Note: Adding a hostname will first remove all entries in the hosts file that match the same hostname.
      This utility will only remove entries from the hosts file that it added.
```

---

## Error Conditions

| Condition | Message (stderr) | Exit Code | Hosts File Modified? |
|-----------|-------------------|-----------|---------------------|
| No subcommand | Usage text (stdout) | 1 | No |
| Unknown subcommand | Usage text (stdout) | 1 | No |
| Missing `-host` (add) | `Error: -host flag is required for the add command` | 1 | No |
| Missing `-server` (add) | `Error: -server flag is required for the add command` | 1 | No |
| Empty `-host` value | `Error: -host flag is required for the add command` | 1 | No |
| DNS resolution failure (all hosts) | `Error: failed to resolve <host>: <reason>` | 1 | No |
| DNS resolution partial failure | Warning per host + entries for successful hosts written | 1 | Yes (partial) |
| Hosts file not found | `Error: file does not exist: <path>` | 1 | No |
| Permission denied | `Error: permission denied: <path>` | 1 | No |
| Corrupt managed block | `Error: managed block is corrupt: <details>` | 1 | No |
| Lock file unavailable | `Error: could not acquire lock file <path>: another instance may be running` | 1 | No |
| Write failure | `Error: writing hosts file: <details>` | 1 | No (atomic write) |

---

## Hosts File Managed Block Format

```
# DNSHelper <<-> START CONFIG
1.2.3.4	hostname1.example.com
5.6.7.8	hostname1.example.com
9.10.11.12	hostname2.example.com
# DNSHelper <->> END CONFIG
```

- Start marker: `# DNSHelper <<-> START CONFIG`
- End marker: `# DNSHelper <->> END CONFIG`
- Each entry: `<IPv4>\t<hostname>` (tab-separated)
- Entries are deduplicated by full line content.
- Block is omitted entirely when there are no managed entries.
