Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 111 additions & 10 deletions .claude/skills/e2e-node-management-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,41 +378,131 @@ ant node status --json

Verify all 3 nodes are `running` before proceeding to cleanup.

### Phase 9: Cleanup
### Phase 9: Log forwarding

**Step 9.1 — Stop all nodes:**
Validates `ant node logs forward` (V2-1021). Forwarding ships node logs to the beta Elasticsearch
endpoint, so this phase must **never** point at the real endpoint. Everything below uses
`--endpoint` against a throwaway local listener, and the phase ends with forwarding disabled.

Note that the nodes added in Phase 6 were added **without** `--log-dir-path`, so they have no log
files. That is the point of Steps 9.1–9.3: the common default must report itself honestly rather
than silently forward nothing.

**Step 9.1 — Status before enabling:**

```
ant node logs forward status --json
```

Verify: `enabled` is `false` and `token_fingerprint` is `null`.

**Step 9.2 — Enable against a local endpoint:**

```
ant node logs forward enable --token e2e-test-token --endpoint http://127.0.0.1:19999 --json
```

Verify: `enabled` is `true`, `endpoint` is the local URL, and `min_level` is `"info"`.

**Step 9.3 — Nodes without logging are reported as skipped:**

Verify from the same response that `nodes_forwarding` is empty and `nodes_skipped` has one entry per
node added in Phase 6, each with a `reason` mentioning `--log-dir-path`. A node with no log
directory writes no log files, so there is nothing to forward and the command must say so.

**Step 9.4 — Add a node with logging and confirm it is picked up:**

```
ant node add --rewards-address 0x03B770D9cD32077cC0bF330c13C114a87643B124 --count 1 --bootstrap <bootstrap-address> --evm-network arbitrum-sepolia --log-dir-path <tmp>/e2e-logs --json
ant node logs forward status --json
```

Verify: `nodes_forwarding` now has one entry, whose `log_dir` is under the path just given.

**Step 9.5 — The token is never returned:**

```
curl -s <api_base>/logs/forward
```

Verify: the response contains `token_fingerprint` but the string `e2e-test-token` appears **nowhere**
in it. The daemon must not hand the write key back out over its API.

**Step 9.6 — Config file permissions (Unix only):**

```
ls -l "${XDG_CONFIG_HOME:-$HOME/.config}/ant/log_forward.json"
```

Verify: the mode is `-rw-------` (0600). The file holds the write token. Skip on Windows.

**Step 9.7 — Enable is reflected in the OpenAPI spec:**

```
curl -s <api_base>/openapi.json | grep -c "logs/forward"
```

Verify: the count is at least 3 (status, enable and disable paths are all documented).

**Step 9.8 — Disable:**

```
ant node logs forward disable --json
ant node logs forward status --json
```

Verify: `enabled` is `false` in both responses, and `active` is `false`. Disabling must not change
anything else about the nodes — confirm with `ant node status --json` that every node's status and
PID are unchanged from before Step 9.2.

**Step 9.9 — Re-enable needs no token:**

```
ant node logs forward enable --json
```

Verify: succeeds without `--token`, reusing the stored one, and reports the same
`token_fingerprint` as Step 9.5. Then disable again so the phase leaves forwarding off:

```
ant node logs forward disable --json
```

### Phase 10: Cleanup

**Step 10.1 — Stop all nodes:**

```
ant node stop --json
```

Verify all nodes stopped.

**Step 9.2 — Reset:**
**Step 10.2 — Reset:**

```
ant node reset --force --json
```

Verify: `nodes_cleared` is 3.

**Step 9.3 — Stop the daemon:**
**Step 10.3 — Stop the daemon:**

```
ant node daemon stop --json
```

Verify: response contains `pid`.

**Step 9.4 — Verify daemon stopped:**
**Step 10.4 — Verify daemon stopped:**

```
ant node daemon status --json
```

Verify: `running` is `false`.

### Phase 10: Report
### Phase 11: Report

Print a summary of all test steps and their results. Include the operating system and architecture
at the top of the report (e.g., from `uname -a` on Linux/macOS or `systeminfo` on Windows):
Expand Down Expand Up @@ -454,10 +544,21 @@ Phase 8: Daemon Restart Adoption
[PASS] 8.7 Liveness monitor detected external kill
[PASS] 8.8 Killed node restarted

Phase 9: Cleanup
[PASS] 9.1 Stop all nodes
[PASS] 9.2 Reset
[PASS] 9.3 Daemon stop
Phase 9: Log Forwarding
[PASS] 9.1 Status before enabling (off)
[PASS] 9.2 Enable against a local endpoint
[PASS] 9.3 Nodes without logging reported as skipped
[PASS] 9.4 Node with --log-dir-path picked up
[PASS] 9.5 Token never returned by the API
[PASS] 9.6 Config file is 0600
[PASS] 9.7 OpenAPI documents the forward paths
[PASS] 9.8 Disable leaves nodes untouched
[PASS] 9.9 Re-enable reuses the stored token

Phase 10: Cleanup
[PASS] 10.1 Stop all nodes
[PASS] 10.2 Reset
[PASS] 10.3 Daemon stop
[PASS] 9.4 Daemon not running

Result: ALL TESTS PASSED
Expand Down
19 changes: 18 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,17 @@ ant-core/src/
│ ├── mod.rs
│ ├── client.rs # Daemon client API (start/stop/status via HTTP)
│ ├── server.rs # HTTP server (axum), REST API handlers
│ └── supervisor.rs # Process supervision with backoff
│ ├── supervisor.rs # Process supervision with backoff
│ └── forward/ # Opt-in beta log forwarding (V2-1021)
│ ├── mod.rs # Status/result types, enable-request merging
│ ├── config.rs # Persisted opt-in + token (0600), LogLevel
│ ├── parse.rs # Log line -> LogEvent (text and JSON layouts)
│ ├── tail.rs # Rotation-aware tailing, multi-line events
│ ├── offsets.rs # Persisted tail positions
│ ├── document.rs # Tagging into the beta index's field names
│ ├── sink.rs # LogSink trait, bounded queue, batching, retry
│ ├── es.rs # Elasticsearch _bulk sink
│ └── runner.rs # The background forwarding task
└── process/
├── mod.rs
├── spawn.rs # Spawning node processes
Expand All @@ -103,6 +113,7 @@ ant-cli/src/
├── mod.rs
├── add.rs # ant node add command
├── daemon.rs # daemon start/stop/status/info/run commands
├── logs.rs # ant node logs forward enable/disable/status
├── start.rs # ant node start
├── stop.rs # ant node stop
├── status.rs # ant node status
Expand Down Expand Up @@ -132,6 +143,12 @@ cargo run --bin ant -- --help # Run the CLI
- **Registry file locking**: Use `NodeRegistry::load_locked()` for read-modify-write operations to prevent concurrent CLI invocations from corrupting the registry. The returned `File` handle holds the lock until dropped.
- **Dual-path CLI commands**: Commands that modify the registry (like `ant node add`) check if the daemon is running. If so, they route through the REST API; otherwise, they operate directly on the registry file.
- **Binary source resolution**: Node binary sources are represented by the `BinarySource` enum (Latest, Version, Url, LocalPath). Download variants are stubbed until release infrastructure is available.
- **Log forwarding is opt-in and node-logging-dependent**: `ant node logs forward enable` is the
consent act. It only forwards nodes whose `NodeConfig.log_dir` is `Some` — node file logging is
off unless the node was added with `--log-dir-path` — and reports the nodes it is skipping.
Enabling never restarts a node or changes its arguments. See
`ant-core/src/node/daemon/forward/` and the V2-1016 ingest contract documented at the top of
`forward/es.rs` (`create` actions, per-position `items[].status`, deterministic `_id`s).

## E2E Test Skill

Expand Down
Loading
Loading