Question
Build an in-memory resolver over A and CNAME records.
```python
class Resolver:
def __init__(self, records: dict[str, dict]): ...
def resolve(self, name: str, now: int = 0) -> str | None: ...
```
## Requirements
- Normalize domain names case-insensitively and ignore a trailing dot.
- An A record resolves directly to its address while live.
- A CNAME follows its target recursively until a live A record is found.
- Each record has `type` (`A` or `CNAME`) and `value` (address or target). Optional `ttl` is a duration; `set_at` defaults to zero. A missing or null `ttl` means no expiration.
- A record expires when `now >= set_at + ttl`.
- Any expired or missing link makes resolution fail.
- Detect alias cycles with a visited set; visiting each normalized name at most once bounds traversal by the finite record set.
- If initial names normalize to the same name, the last entry in input order wins.
The fixture interface is `run_case(case)`: `case.records` contains the initial mapping and `case.lookups` is an ordered list of `{name, now}` queries. Return one address or `None` per query. The supplied adapter creates a fresh resolver for each case; implement the class methods without replacing the adapter.
## Implementation approach
1. Implement normalized A-record lookup.
2. Add CNAME chains and cycle safety.
3. Enforce TTL expiration on every link, including the exact boundary.
## Design discussion (not graded by these fixtures)
Discuss record mutation and replacement, positive and negative caching that respects remaining TTL, concurrent updates, delegation, multiple record values, and cache poisoning defenses. These require separately specified interfaces and tests; they are not extra implemented methods in this task.