docs(issue-42): review - attach names the herdr server, --dry-run is not "write nothing", a deleted block stays deleted
Merge-workspace review of PR #46 (codex R1-R3 and C1, claude O1 and O4). - R1: resume never attaches, and the server it exports does not reach the calling shell; the native herdr binary does not route on environment variables. The attach advice and the Verification block now name the server: `herdr --session <server> agent attach <name>`, with <server> the row's herdr_session. - R2: --dry-run in resume and create skips the spawn and the registry update, but the checks before it still run and on macOS remove the quarantine attribute from the agent binary. The option rows say so. - R3: test_no_deleted_body_came_back compares every current block with the deleted bodies by exact sha and by a whitespace-insensitive fingerprint (stored as base_fingerprint), independently of the inventory, so a deleted block cannot return by being listed again under class c. Replaying the review's probe (the deleted resume Workflow re-added and inventoried as c) fails the new test and passes the old one. - C1 / O1: the base create call block at 263-266 (class c) folded into the Workflow call is recorded under "superseded"; the 37 base blocks are all accounted for. - O4: create exit 42 also covers MAM_KILL_ON_READY_TIMEOUT=1; stop's no-op exit 0 does not apply with --purge-conversation. - The inventory's positions and shas are regenerated for the edited blocks; every classification is unchanged. No product code changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
1 parent
8d26106195
commit
17eba0904e
5 files changed
+92
-18
No files matched your search
@@ -161,7 +161,7 @@ bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace
|
|||||||
| `--role` | Required. Assigned role |
|
| `--role` | Required. Assigned role |
|
||||||
| `--session` (`--name`) | herdr session name (default: `derive_session_name`) |
|
| `--session` (`--name`) | herdr session name (default: `derive_session_name`) |
|
||||||
| `--wrapper` | claude only: use the `~/.local/bin/<session>` wrapper even if it is not present |
|
| `--wrapper` | claude only: use the `~/.local/bin/<session>` wrapper even if it is not present |
|
||||||
| `--dry-run` | Print what would be spawned; spawn and write nothing |
|
| `--dry-run` | Print what would be spawned; no spawn and no registry (YAML/DB) update. The checks before it still run, and on macOS they remove the quarantine attribute from the agent binary |
|
||||||
| `--herdr-session` (`--herdr-server`) | Isolated herdr server name |
|
| `--herdr-session` (`--herdr-server`) | Isolated herdr server name |
|
||||||
| `--herdr-workspace` | herdr workspace label recorded in the registry (a label only, never a socket) |
|
| `--herdr-workspace` | herdr workspace label recorded in the registry (a label only, never a socket) |
|
||||||
| `--submit-job PROMPT` | Register a delegated job with this prompt and send it to the new agent |
|
| `--submit-job PROMPT` | Register a delegated job with this prompt and send it to the new agent |
|
||||||
@@ -176,7 +176,7 @@ bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace
|
|||||||
| 2 | Bad arguments; control-plane binding refused for a worktree; whitespace in a control-plane path that must be forwarded |
|
| 2 | Bad arguments; control-plane binding refused for a worktree; whitespace in a control-plane path that must be forwarded |
|
||||||
| 3 | A herdr session of that name already exists (`multi-agent-mux-resume`, or `multi-agent-mux-stop` first) |
|
| 3 | A herdr session of that name already exists (`multi-agent-mux-resume`, or `multi-agent-mux-stop` first) |
|
||||||
| 4 | The YAML already has a `running` row of that name. The YAML write raises it after spawn, and the herdr session is rolled back |
|
| 4 | The YAML already has a `running` row of that name. The YAML write raises it after spawn, and the herdr session is rolled back |
|
||||||
| 42 | The TUI never became ready and the process is gone |
|
| 42 | The TUI never became ready and the process is gone, or it is alive and `MAM_KILL_ON_READY_TIMEOUT=1` (rolled back) |
|
||||||
| 43 | The rollback could not kill the herdr session; it is still running |
|
| 43 | The rollback could not kill the herdr session; it is still running |
|
||||||
| other | A later step failed and its code is passed through. The EXIT trap (`cleanup_herdr_on_error`) rolls back the herdr session and closes the onboarding job as `cancelled`; if that kill fails, the exit is 43 instead |
|
| other | A later step failed and its code is passed through. The EXIT trap (`cleanup_herdr_on_error`) rolls back the herdr session and closes the onboarding job as `cancelled`; if that kill fails, the exit is 43 instead |
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Three cases this skill handles:
|
|||||||
|
|
||||||
1. **herdr is dead, conversation lives** — `agent-sessions.yaml` has the UUID. The JSONL/db is on disk. Re-spawn the herdr session + run `claude -r <id>` / `agy --conversation <id>`.
|
1. **herdr is dead, conversation lives** — `agent-sessions.yaml` has the UUID. The JSONL/db is on disk. Re-spawn the herdr session + run `claude -r <id>` / `agy --conversation <id>`.
|
||||||
2. **herdr is alive but empty** — You started a session with `multi-agent-mux-create` but haven't sent a message yet (so no session id was assigned). The user can either send their first message (and the id is auto-assigned), or you can read the *workspace's* most recent conversation from `$HOME_DIR/.gemini/antigravity-cli/cache/last_conversations.json` (defaults to `~/.gemini/...`) for agy, or the latest `*.jsonl` in `$CLAUDE_PROJECT_DIR/<workspace-key>/` (defaults to `~/.claude/projects/`) for claude.
|
2. **herdr is alive but empty** — You started a session with `multi-agent-mux-create` but haven't sent a message yet (so no session id was assigned). The user can either send their first message (and the id is auto-assigned), or you can read the *workspace's* most recent conversation from `$HOME_DIR/.gemini/antigravity-cli/cache/last_conversations.json` (defaults to `~/.gemini/...`) for agy, or the latest `*.jsonl` in `$CLAUDE_PROJECT_DIR/<workspace-key>/` (defaults to `~/.claude/projects/`) for claude.
|
||||||
3. **herdr is alive AND the agent inside is already running** — `resume_session.sh` only updates the row and exits 0. It does not attach and does not check the agent's permission flags (#45); attach with `herdr agent attach <name>`.
|
3. **herdr is alive AND the agent inside is already running** — `resume_session.sh` only updates the row and exits 0. It does not attach and does not check the agent's permission flags (#45); attach with `herdr --session <server> agent attach <name>`, where `<server>` is the row's `herdr_session` (the server it was resumed on).
|
||||||
|
|
||||||
### Resuming a `stopped` session (`stopped → running`)
|
### Resuming a `stopped` session (`stopped → running`)
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ If both are empty → for Class A agents (`agy`, `hermes`, `opencode`, `codex`),
|
|||||||
bash .agents/skills/multi-agent-mux-resume/scripts/resume_session.sh --workspace <path> --agent <agent> --session <name>
|
bash .agents/skills/multi-agent-mux-resume/scripts/resume_session.sh --workspace <path> --agent <agent> --session <name>
|
||||||
```
|
```
|
||||||
|
|
||||||
`resume_session.sh` does the whole flow: original-cwd check, control-plane binding, session-id resolution (`resolve_session_id.sh`), the herdr-alive check, the agent command (adapter `resume-spec`, or `spawn-spec` for a Class A fresh spawn), spawn, start-up dialogs, and the YAML update (`update_yaml_resumed.sh`, which also publishes a `progress "resumed"` event when the row has a `delegate_job_id`). It never attaches; attaching is a separate step: `herdr agent attach <name>`.
|
`resume_session.sh` does the whole flow: original-cwd check, control-plane binding, session-id resolution (`resolve_session_id.sh`), the herdr-alive check, the agent command (adapter `resume-spec`, or `spawn-spec` for a Class A fresh spawn), spawn, start-up dialogs, and the YAML update (`update_yaml_resumed.sh`, which also publishes a `progress "resumed"` event when the row has a `delegate_job_id`). It never attaches; attaching is a separate step that names the server, because the server the script exports does not reach the calling shell and the native `herdr` binary does not route on environment variables: `herdr --session <server> agent attach <name>` (`<server>` = the `--herdr-session` you passed, or the row's `herdr_session`).
|
||||||
|
|
||||||
| Option | Meaning |
|
| Option | Meaning |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -70,7 +70,7 @@ bash .agents/skills/multi-agent-mux-resume/scripts/resume_session.sh --workspace
|
|||||||
| `--herdr-session` (`--herdr-server`) | Isolated herdr server name |
|
| `--herdr-session` (`--herdr-server`) | Isolated herdr server name |
|
||||||
| `--herdr-workspace` | herdr workspace label |
|
| `--herdr-workspace` | herdr workspace label |
|
||||||
| `--auto-trust` / `--no-auto-trust` | Answer a start-up directory-trust dialog or leave it to a human (`MAM_AUTO_TRUST`; default: answer) |
|
| `--auto-trust` / `--no-auto-trust` | Answer a start-up directory-trust dialog or leave it to a human (`MAM_AUTO_TRUST`; default: answer) |
|
||||||
| `--dry-run` | Resolve the command and print it; write nothing |
|
| `--dry-run` | Resolve the command and print it; no spawn and no registry (YAML/DB) update. The checks before it still run, and on macOS they remove the quarantine attribute from the agent binary |
|
||||||
|
|
||||||
| Exit | Meaning |
|
| Exit | Meaning |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -101,8 +101,12 @@ A session is resumed only in the directory it ran in (its row's `pane.cwd`): the
|
|||||||
## Verification
|
## Verification
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# The server the session runs on (its row's herdr_session); the native herdr
|
||||||
|
# binary needs it as --session, an exported variable is not enough.
|
||||||
|
SERVER=$(python3 -c "import yaml; d = yaml.safe_load(open('.mam/agent-sessions.yaml')); print([s for s in d['herdr_sessions'] if s['name'] == '$SESSION_NAME'][0].get('herdr_session') or 'default')")
|
||||||
|
|
||||||
# 1. herdr alive with the right cmd (real native command, no lib.sh needed)
|
# 1. herdr alive with the right cmd (real native command, no lib.sh needed)
|
||||||
herdr agent get "$SESSION_NAME" | python3 -c "
|
herdr --session "$SERVER" agent get "$SESSION_NAME" | python3 -c "
|
||||||
import sys, json
|
import sys, json
|
||||||
a = json.load(sys.stdin)['result']['agent']
|
a = json.load(sys.stdin)['result']['agent']
|
||||||
print(f\"cmd={a['agent']} cwd={a['cwd']}\")
|
print(f\"cmd={a['agent']} cwd={a['cwd']}\")
|
||||||
@@ -119,7 +123,7 @@ print(f' pane.cmd_full: {s[\"pane\"][\"cmd_full\"]}')
|
|||||||
|
|
||||||
# 3. TUI shows resumed conversation (real native command, no lib.sh needed)
|
# 3. TUI shows resumed conversation (real native command, no lib.sh needed)
|
||||||
sleep 5
|
sleep 5
|
||||||
herdr agent read "$SESSION_NAME" --source visible --lines 30
|
herdr --session "$SERVER" agent read "$SESSION_NAME" --source visible --lines 30
|
||||||
# look for the previous message at top of the buffer (claude) or last_visible_status set (agy)
|
# look for the previous message at top of the buffer (claude) or last_visible_status set (agy)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -132,4 +136,4 @@ herdr agent read "$SESSION_NAME" --source visible --lines 30
|
|||||||
|
|
||||||
- **No saved session yet** → `multi-agent-mux-create`
|
- **No saved session yet** → `multi-agent-mux-create`
|
||||||
- **Killing an existing session** → `multi-agent-mux-stop`
|
- **Killing an existing session** → `multi-agent-mux-stop`
|
||||||
- **Just attaching** → `herdr agent attach <name>` (no skill needed)
|
- **Just attaching** → `herdr --session <server> agent attach <name>` (no skill needed; `<server>` = the row's `herdr_session`)
|
||||||
@@ -58,7 +58,7 @@ bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh \
|
|||||||
|
|
||||||
| Exit | Meaning |
|
| Exit | Meaning |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 0 | Stopped; or already `stopped` (no-op) |
|
| 0 | Stopped; or already `stopped` (no-op, except with `--purge-conversation`, which still purges) |
|
||||||
| 1 | From the checks before the stop, nothing was changed: YAML not found, or the session is not registered. **The registry update after the stop also exits 1** (the row disappeared from the YAML during the run) |
|
| 1 | From the checks before the stop, nothing was changed: YAML not found, or the session is not registered. **The registry update after the stop also exits 1** (the row disappeared from the YAML during the run) |
|
||||||
| 2 | Bad arguments (including the retired `--mode` / `--capture-id` / `--graceful`), or `--agent` omitted and not resolvable |
|
| 2 | Bad arguments (including the retired `--mode` / `--capture-id` / `--graceful`), or `--agent` omitted and not resolvable |
|
||||||
| 3 | `--purge-conversation` without `--yes` |
|
| 3 | `--purge-conversation` without `--yes` |
|
||||||
|
|||||||
@@ -339,9 +339,9 @@
|
|||||||
{
|
{
|
||||||
"skill": "multi-agent-mux-resume",
|
"skill": "multi-agent-mux-resume",
|
||||||
"start": 103,
|
"start": 103,
|
||||||
"end": 124,
|
"end": 128,
|
||||||
"lang": "bash",
|
"lang": "bash",
|
||||||
"sha": "f4bddf5ba4d1",
|
"sha": "8a468dfa43bd",
|
||||||
"class": "b",
|
"class": "b",
|
||||||
"kind": "verification",
|
"kind": "verification",
|
||||||
"evidence": [],
|
"evidence": [],
|
||||||
@@ -492,7 +492,8 @@
|
|||||||
],
|
],
|
||||||
"replacement": "bash .agents/skills/multi-agent-mux-resume/scripts/resume_session.sh --workspace <path> --agent <agent> --session <name>",
|
"replacement": "bash .agents/skills/multi-agent-mux-resume/scripts/resume_session.sh --workspace <path> --agent <agent> --session <name>",
|
||||||
"script": "multi-agent-mux-resume/scripts/resume_session.sh",
|
"script": "multi-agent-mux-resume/scripts/resume_session.sh",
|
||||||
"note": "Workflow re-wrote resume_session.sh in bash"
|
"note": "Workflow re-wrote resume_session.sh in bash",
|
||||||
|
"base_fingerprint": "cd4000a4afae"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"skill": "multi-agent-mux-stop",
|
"skill": "multi-agent-mux-stop",
|
||||||
@@ -511,7 +512,8 @@
|
|||||||
],
|
],
|
||||||
"replacement": "bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh",
|
"replacement": "bash .agents/skills/multi-agent-mux-stop/scripts/stop_session.sh",
|
||||||
"script": "multi-agent-mux-stop/scripts/stop_session.sh",
|
"script": "multi-agent-mux-stop/scripts/stop_session.sh",
|
||||||
"note": "pre-flight (registered? already stopped?); replaced by one prose line, the Workflow block already calls the entry point"
|
"note": "pre-flight (registered? already stopped?); replaced by one prose line, the Workflow block already calls the entry point",
|
||||||
|
"base_fingerprint": "f2e5380dbaa4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"skill": "multi-agent-mux-create",
|
"skill": "multi-agent-mux-create",
|
||||||
@@ -531,7 +533,8 @@
|
|||||||
],
|
],
|
||||||
"replacement": "bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace <path> --agent <agent> --role <role>",
|
"replacement": "bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace <path> --agent <agent> --role <role>",
|
||||||
"script": "multi-agent-mux-create/scripts/create_session.sh",
|
"script": "multi-agent-mux-create/scripts/create_session.sh",
|
||||||
"note": "pre-flight; replaced by prose, the has_real_herdr vs command -v pitfall kept as prose"
|
"note": "pre-flight; replaced by prose, the has_real_herdr vs command -v pitfall kept as prose",
|
||||||
|
"base_fingerprint": "6caf3573a587"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"skill": "multi-agent-mux-create",
|
"skill": "multi-agent-mux-create",
|
||||||
@@ -554,7 +557,8 @@
|
|||||||
],
|
],
|
||||||
"replacement": "bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace <path> --agent <agent> --role <role>",
|
"replacement": "bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace <path> --agent <agent> --role <role>",
|
||||||
"script": "multi-agent-mux-create/scripts/create_session.sh",
|
"script": "multi-agent-mux-create/scripts/create_session.sh",
|
||||||
"note": "Workflow re-wrote create_session.sh in bash"
|
"note": "Workflow re-wrote create_session.sh in bash",
|
||||||
|
"base_fingerprint": "bc8eec474b36"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"skill": "multi-agent-mux-create",
|
"skill": "multi-agent-mux-create",
|
||||||
@@ -569,7 +573,8 @@
|
|||||||
"mismatch": [],
|
"mismatch": [],
|
||||||
"replacement": "bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace <path> --agent <agent> --role <role>",
|
"replacement": "bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace <path> --agent <agent> --role <role>",
|
||||||
"script": "multi-agent-mux-create/scripts/create_session.sh",
|
"script": "multi-agent-mux-create/scripts/create_session.sh",
|
||||||
"note": "manual \"append this row\" step; the script writes the row. The lib.sh shim note (base 248-251) moved to prose under Output format"
|
"note": "manual \"append this row\" step; the script writes the row. The lib.sh shim note (base 248-251) moved to prose under Output format",
|
||||||
|
"base_fingerprint": "b8ff0badf537"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"entry_points": {
|
"entry_points": {
|
||||||
@@ -620,5 +625,19 @@
|
|||||||
"C6: create_session.sh header lists exit 4 \"YAML append failure\"; there is no literal `exit 4`, but the YAML write raises SystemExit(4) for a duplicate running row (create_session.sh:515) and it passes through, so 4 IS a real exit code (the plan assumed it was not)",
|
"C6: create_session.sh header lists exit 4 \"YAML append failure\"; there is no literal `exit 4`, but the YAML write raises SystemExit(4) for a duplicate running row (create_session.sh:515) and it passes through, so 4 IS a real exit code (the plan assumed it was not)",
|
||||||
"R6: resume's \"The script above re-passes them\" and \"as done in Workflow above\" pointed at the removed block; reworded (same for create's Verification note)",
|
"R6: resume's \"The script above re-passes them\" and \"as done in Workflow above\" pointed at the removed block; reworded (same for create's Verification note)",
|
||||||
"R7 (review 08e1f1b2): stop's table said exit 1 is always pre-stop; the registry update after the kill chain also raises SystemExit(1) (stop_session.sh:310) when the row disappeared"
|
"R7 (review 08e1f1b2): stop's table said exit 1 is always pre-stop; the registry update after the kill chain also raises SystemExit(1) (stop_session.sh:310) when the row disappeared"
|
||||||
|
],
|
||||||
|
"superseded": [
|
||||||
|
{
|
||||||
|
"skill": "multi-agent-mux-create",
|
||||||
|
"base_start": 263,
|
||||||
|
"base_end": 266,
|
||||||
|
"lang": "bash",
|
||||||
|
"base_sha": "ceb96a8c1293",
|
||||||
|
"class": "c",
|
||||||
|
"kind": "invocation",
|
||||||
|
"replacement": "bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh",
|
||||||
|
"note": "The base call example under 'Updating agent-sessions.yaml' (with the nonexistent agent-sessions-yaml-edit script above it, prose_mismatches C4) is folded into the Workflow call block; no information lost.",
|
||||||
|
"base_fingerprint": "b6a8a25279c5"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,10 @@ tests/data/skill_code_blocks.json lists every fenced block of the eight
|
|||||||
SKILL.md files with its class - (b) a procedure no script offers yet, (c) an
|
SKILL.md files with its class - (b) a procedure no script offers yet, (c) an
|
||||||
example, call or diagram - and the (a) blocks removed because the entry script
|
example, call or diagram - and the (a) blocks removed because the entry script
|
||||||
already does them. These tests fail when a SKILL.md block changes without the
|
already does them. These tests fail when a SKILL.md block changes without the
|
||||||
inventory, when an (a) block comes back, or when an exit-code table drifts from
|
inventory, when a deleted block's body comes back (by exact sha or by a
|
||||||
the entry script.
|
whitespace-insensitive fingerprint, whatever the inventory says about it), or
|
||||||
|
when an exit-code table drifts from the entry script. A (c) block folded into
|
||||||
|
another call is recorded under "superseded".
|
||||||
"""
|
"""
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
@@ -127,6 +129,55 @@ def test_no_duplicate_block_left():
|
|||||||
assert r["class"] == "a", r
|
assert r["class"] == "a", r
|
||||||
|
|
||||||
|
|
||||||
|
def fingerprint(body):
|
||||||
|
"""A deleted body's identity that survives reindenting and reflowing."""
|
||||||
|
return hashlib.sha256(" ".join(body.split()).encode()).hexdigest()[:12]
|
||||||
|
|
||||||
|
|
||||||
|
def _returned_bodies(texts, gone):
|
||||||
|
"""(skill, start, which) for each current block whose body is a deleted one."""
|
||||||
|
hits = []
|
||||||
|
for skill, text in texts.items():
|
||||||
|
for start, _end, _lang, sha, body in parse_blocks(text):
|
||||||
|
for g in gone:
|
||||||
|
if sha == g["base_sha"] or fingerprint(body) == g["base_fingerprint"]:
|
||||||
|
hits.append((skill, start, f"{g['skill']}:{g['base_start']}"))
|
||||||
|
return hits
|
||||||
|
|
||||||
|
|
||||||
|
# 2b. A deleted body stays deleted - even when the inventory is updated to list
|
||||||
|
# it again under another class (review R3).
|
||||||
|
def test_no_deleted_body_came_back():
|
||||||
|
gone = DATA["removed"] + DATA["superseded"]
|
||||||
|
texts = {s: skill_text(s) for s in SKILL_NAMES}
|
||||||
|
assert _returned_bodies(texts, gone) == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_returned_body_is_caught_reindented_and_with_the_inventory_updated():
|
||||||
|
"""The guard itself: a current block posing as a deleted one is found by its
|
||||||
|
exact sha and, reindented, by its fingerprint; listing it in the inventory
|
||||||
|
does not hide it (that check never reads DATA["blocks"])."""
|
||||||
|
skill = "multi-agent-mux-stop"
|
||||||
|
start, _end, _lang, sha, body = parse_blocks(skill_text(skill))[0]
|
||||||
|
fake = {"skill": skill, "base_start": 1, "base_sha": sha, "base_fingerprint": fingerprint(body)}
|
||||||
|
assert _returned_bodies({skill: skill_text(skill)}, [fake]) == [(skill, start, f"{skill}:1")]
|
||||||
|
reindented = "\n".join(" " + line for line in body.split("\n"))
|
||||||
|
other = {"skill": skill, "base_start": 1, "base_sha": "0" * 12, "base_fingerprint": fingerprint(reindented)}
|
||||||
|
assert _returned_bodies({skill: skill_text(skill)}, [other]) == [(skill, start, f"{skill}:1")]
|
||||||
|
|
||||||
|
|
||||||
|
# 2c. A deleted (c) block folded into another call is recorded too (review C1):
|
||||||
|
# with it the 37 base blocks are all accounted for.
|
||||||
|
def test_superseded_blocks_are_recorded_and_replaced():
|
||||||
|
assert DATA["superseded"], "the folded create call is recorded"
|
||||||
|
for r in DATA["superseded"]:
|
||||||
|
assert r["class"] == "c" and r["kind"] in KINDS, r
|
||||||
|
bodies = [b[4] for b in parse_blocks(skill_text(r["skill"]))]
|
||||||
|
assert any(r["replacement"] in body for body in bodies), r
|
||||||
|
for r in DATA["removed"] + DATA["superseded"]:
|
||||||
|
assert re.fullmatch(r"[0-9a-f]{12}", r["base_fingerprint"]), r
|
||||||
|
|
||||||
|
|
||||||
# 3. A removed block is replaced by the entry-point call.
|
# 3. A removed block is replaced by the entry-point call.
|
||||||
@pytest.mark.parametrize("removed", DATA["removed"], ids=lambda r: f"{r['skill']}:{r['base_start']}")
|
@pytest.mark.parametrize("removed", DATA["removed"], ids=lambda r: f"{r['skill']}:{r['base_start']}")
|
||||||
def test_removed_block_replaced_by_entry_call(removed):
|
def test_removed_block_replaced_by_entry_call(removed):
|
||||||
|
|||||||
Reference in new issue
Block a user