5 Commits

Author SHA1 Message Date
13a562e966 chore: wire hxprobe into root project (Makefile, CLAUDE.md, .gitignore)
Makefile: add hx-* targets (deps, run, lint, fmt, test, test-integration,
check, clean) that delegate into hxprobe/ via uv; fold hx-test and hx-check
into the umbrella test/check/clean targets; add HX_DIR variable and a note
that hxprobe is intentionally standalone (no cross-imports from python/).

CLAUDE.md: add "Implementation Summaries" convention — after each feature,
save a summary under docs/summaries/ with the same timestamp+slug naming as
plans. Add note about copying plan-mode scratch files into docs/plans/ before
starting implementation.

.gitignore: add *.egg-info/, .pytest_cache/, .ruff_cache/ for the hxprobe
uv+ruff+pytest toolchain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 13:22:43 +02:00
24ea9c9e71 feat(py): step 3 — full latprobe package with --verbose flag
Adds the complete Python port of the Go latprobe tool plus diagnostic
verbose output that the Go version does not yet have.

Package (python/latprobe/):
- probe.py: raw-socket HTTP timing with CertInfo/VerboseDetail dataclasses;
  TTFB loop accumulates to \r\n\r\n so headers are parseable without changing
  t_first_byte semantics; captures resolved IP, TLS version/cipher/bits,
  verified cert (via getpeercert()), and all response headers when verbose=True
- aggregate.py: summarize() → per-phase min/avg/max PhaseStats
- cli.py: injectable run(args,stdout,stderr)->int; argparse with injected
  streams; ThreadPoolExecutor concurrency across URLs; four text-rendering
  branches; JSON output; worst-exit-code accumulation; -v/--verbose flag
  appends IP/TLS/cert/header block after every timing table; JSON extended
  with "verbose" object (omitted when flag absent)
- duration.py: parse Go-style duration strings (10s, 500ms, 2m, bare seconds)
- Exit codes: 0 ok, 1 usage, 2 dns, 3 connect, 4 timeout, 5 tls, 6 http≥400

Tests:
- test_probe.py: 18 hermetic tests (success, 404, DNS/connect/timeout/scheme
  failures, partial-phase invariants, verbose detail fields)
- test_cli.py: 38 hermetic tests (usage errors, single/aggregate/failure text,
  worst-code, --fail, JSON schema/ordering/grouping, verbose text and JSON)
- test_integration.py: 45 tests against live internet services (badssl.com for
  TLS errors, real cert/IP/header validation in verbose mode)

Makefile: PYTHONPATH fix, fnmatch pattern test_[!i]*.py to exclude
integration tests from py-test, new py-test-integration target

Docs: docs/usage/py-latprobe.md, python/configs/usage-latprobe.md (runnable
reference with captured output), plans for both the package and verbose feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 13:45:56 +02:00
49838e9e4c feat(py): step 1 — simple reachability checker (simple.py)
- python/simple.py: reads a plain-text site list (one URL/line, # comments),
  issues a GET per site, prints aligned OK/FAIL + elapsed ms, exits 0/1
- Config format forward-compatible with future key=value annotations
- HTTPError caught separately from URLError so HTTP status code appears in
  the FAIL message (e.g. "HTTP Error 404: Not Found")
- python/sites.txt: committed example config
- Makefile: PYTHON/PY_DIR/SITES vars; py-simple-run, py-phases-run, py-run,
  py-test, py-check, py-clean targets; umbrella test/check/clean include Python
- docs/plans/2026-07-01-10-39-py-simple.md: design plan
- docs/usage/py-simple.md: flags, format, examples, limitations

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 11:58:10 +02:00
9a69ba946f Add URL-level concurrency (-c flag, Step 7)
Probe multiple URLs in parallel with a bounded worker pool; the N samples
of each URL remain sequential to preserve accurate min/avg/max statistics.
Default auto-concurrency is min(numURLs, 8); -c 1 restores serial mode.
Output is always buffered and printed in original input order. Verified
clean with go test -race.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 01:33:03 +02:00
0cf5b54070 chore: add root Makefile with namespaced targets
Namespaced go-* targets (build, run, test, test-verbose, check, cover,
fmt, vet, tidy, install, lint, clean) plus umbrella targets that delegate
to them. help is the default. py-* targets will slot in during the Python
port. Updates .gitignore with coverage artifacts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 01:08:51 +02:00