assertion-cli 0.5.1__tar.gz → 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/PKG-INFO +1 -1
  2. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/assertion_cli.egg-info/PKG-INFO +1 -1
  3. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/main.py +23 -2
  4. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/pyproject.toml +1 -1
  5. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/templates/ACTIVATION.md +4 -5
  6. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/templates/SKILL.md +19 -14
  7. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_link.py +21 -0
  8. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/README.md +0 -0
  9. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/api.py +0 -0
  10. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/assertion_cli.egg-info/SOURCES.txt +0 -0
  11. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/assertion_cli.egg-info/dependency_links.txt +0 -0
  12. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/assertion_cli.egg-info/entry_points.txt +0 -0
  13. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/assertion_cli.egg-info/requires.txt +0 -0
  14. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/assertion_cli.egg-info/top_level.txt +0 -0
  15. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/bundle.py +0 -0
  16. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/git.py +0 -0
  17. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/link.py +0 -0
  18. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/models.py +0 -0
  19. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/session.py +0 -0
  20. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/setup.cfg +0 -0
  21. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/templates/__init__.py +0 -0
  22. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_api.py +0 -0
  23. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_bundle.py +0 -0
  24. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_decision.py +0 -0
  25. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_git.py +0 -0
  26. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_init.py +0 -0
  27. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_main.py +0 -0
  28. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_prompt.py +0 -0
  29. {assertion_cli-0.5.1 → assertion_cli-0.5.2}/tests/test_session.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assertion-cli
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: CLI for the Assertion API
5
5
  Requires-Python: >=3.13
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assertion-cli
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: CLI for the Assertion API
5
5
  Requires-Python: >=3.13
6
6
  Description-Content-Type: text/markdown
@@ -546,12 +546,33 @@ def verify_status(
546
546
  raise typer.Exit(code=1)
547
547
 
548
548
 
549
+ PR_SESSION_MARKER_LABEL = "assertion-session:"
550
+
551
+
552
+ def render_pr_session_marker(url: str) -> str:
553
+ """Render the hidden PR marker the Assertion GitHub bot parses.
554
+
555
+ An HTML comment: GitHub hides it from the rendered PR description but
556
+ delivers it verbatim in the webhook payload, so the bot can match a PR to
557
+ its verification session when the branch name doesn't line up. Keep the
558
+ format in sync with the parser in backend `api/v0/webhooks/router.py`.
559
+ """
560
+ return f"<!-- {PR_SESSION_MARKER_LABEL} {url} -->"
561
+
562
+
549
563
  @app.command("get-link")
550
564
  def get_link() -> None:
551
- """Print the session link for the current verification session."""
565
+ """Print the hidden PR marker for the current verification session.
566
+
567
+ Emits `<!-- assertion-session: <url> -->`. Paste it into the PR body so the
568
+ Assertion GitHub bot can link the PR to this session when the branch name
569
+ doesn't match. GitHub does not render HTML comments, so it stays out of the
570
+ visible description. (The bare session URL is printed by `asrt verify` /
571
+ `asrt verify-status` and stored in `.assertion/link`.)
572
+ """
552
573
  ctx, metadata = load_existing_session(Path.cwd())
553
574
  url = load_link(ctx.assertion_dir)
554
- typer.echo(url)
575
+ typer.echo(render_pr_session_marker(url))
555
576
 
556
577
 
557
578
  @app.command("decision")
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "assertion-cli"
7
- version = "0.5.1"
7
+ version = "0.5.2"
8
8
  description = "CLI for the Assertion API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -9,13 +9,12 @@ Both files are byte-identical. Read whichever your agent loads (or either one di
9
9
 
10
10
  1. **Every user message:** call `asrt prompt "<exact text of the message>"` before doing any other work for that turn. This is the verifier's source of truth for what the user asked for and how their direction evolves. Apply to every user turn, not just the first.
11
11
  2. **Checkpoint at trajectory-feedback moments**, not on every small change. On the first checkpoint of a session, run `asrt stacks`, pick the stack that fits this repo and the work (use the stack's `repo`, `name`, `description`, plus folder/branch/README signals), then run `asrt checkpoint --stack <id> "<summary>"`. Subsequent checkpoints in the same session don't need `--stack` — `asrt checkpoint "<summary>"` auto-continues. A whole feature build is a handful of checkpoints, not one per file.
12
- 3. **Verify at completion** with `asrt verify`. If feedback requires changes, iterate and re-verify — do **not** drop back into the checkpoint loop. Once verify is clean, open a PR and **put the Assertion session URL in the PR description** — this is required, not optional. Read the URL from `asrt get-link` (don't paste from memory) and include it on its own labeled line:
12
+ 3. **Verify at completion** with `asrt verify`. If feedback requires changes, iterate and re-verify — do **not** drop back into the checkpoint loop. Once verify is clean, open a PR and **embed the hidden Assertion session marker in its body** — this is required, not optional. The marker (`asrt get-link`) is an HTML comment GitHub hides from the rendered description but delivers to the Assertion GitHub bot, which uses it to link the PR to the verification when the branch name doesn't match:
13
13
 
14
14
  ```
15
- SESSION_URL=$(asrt get-link)
16
- gh pr create --title "<title>" --body "$(printf '%s\n\n**Assertion verification:** %s\n' '<one-paragraph why>' "$SESSION_URL")"
15
+ gh pr create --title "<title>" --body "$(printf '%s\n\n%s\n' '<one-paragraph why>' "$(asrt get-link)")"
17
16
  ```
18
17
 
19
- If a PR already exists for the branch, add the line with `gh pr edit --body` instead of opening a new one.
18
+ If a PR already exists for the branch, add the marker with `gh pr edit --body` instead of opening a new one.
20
19
 
21
- Do not open a PR without a clean `asrt verify`, and do not open one whose description omits the session URL.
20
+ Do not open a PR without a clean `asrt verify`, and do not open one whose body omits the session marker.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: assertion-cli
3
- description: Use this skill in non-Plan mode whenever working in a repo that uses the Assertion CLI (`asrt`). It enforces the three-rule workflow — log every user message with `asrt prompt`, checkpoint at trajectory-feedback moments (not on every change), and verify only at completion before opening a PR whose description includes the Assertion session URL. Applies to any coding agent reading this skill.
3
+ description: Use this skill in non-Plan mode whenever working in a repo that uses the Assertion CLI (`asrt`). It enforces the three-rule workflow — log every user message with `asrt prompt`, checkpoint at trajectory-feedback moments (not on every change), and verify only at completion before opening a PR whose body embeds the hidden Assertion session marker. Applies to any coding agent reading this skill.
4
4
  ---
5
5
 
6
6
  # Assertion CLI
@@ -137,46 +137,51 @@ done
137
137
 
138
138
  `asrt verify-status` is a one-shot poll. It prints the current status, refreshes `.assertion/link`, and on terminal status writes screenshots under `.assertion/screenshots/<verification_id>/`. Exit code is `0` for `created` / `running` / `succeeded` and `1` for `failed`, so a polling loop can also branch on `$?`.
139
139
 
140
- `asrt get-link` prints the last session URLthe verification record reviewers open from the PR. Every PR you open from an Assertion session must carry this URL in its description (see *Put the session URL in the PR description* below).
140
+ `asrt get-link` prints the hidden PR markeran HTML comment carrying the session URL. Every PR you open from an Assertion session must embed it in the body so the Assertion GitHub bot can link the PR to the verification session — even when the branch name doesn't match (see *Embed the hidden session marker in the PR* below). The bare session URL, if you need it for something else, is printed by `asrt verify` / `asrt verify-status`.
141
141
 
142
142
  **After status reports terminal, branch on the outcome:**
143
143
 
144
144
  | Outcome | What you do next |
145
145
  |---|---|
146
- | **Clean** (succeeded, no required changes) | Open a PR and **put the session URL in the PR description** — mandatory, not optional. Use the exact command in *Put the session URL in the PR description* below. |
146
+ | **Clean** (succeeded, no required changes) | Open a PR and **embed the hidden session marker in its body** — mandatory, not optional. Use the exact command in *Embed the hidden session marker in the PR* below. |
147
147
  | **Feedback or failed** (changes required) | Treat the feedback as authoritative. Apply the changes it calls for, then re-run `asrt verify` and poll `asrt verify-status` again. Repeat until clean. **Do not drop back into the checkpoint loop** — verify is the gate, not a checkpoint. |
148
148
  | **User sends a new message during iteration** | Log it with `asrt prompt` first (Rule 1 still applies). Address the new direction. Re-verify before opening the PR. |
149
149
 
150
- ### Put the session URL in the PR description (required)
150
+ ### Embed the hidden session marker in the PR (required)
151
151
 
152
- Every PR opened from an Assertion session **must** include the verification session URL in its description. That URL is the reviewer's link to the verification record; a PR without it is incomplete. Do not bury it in a PR comment and do not omit it.
152
+ Every PR opened from an Assertion session **must** carry the session marker in its body. The Assertion GitHub bot links a PR to its verification session by **branch name first**; when that doesn't match (you renamed the branch, or the PR's head ref differs from the one you verified on), it falls back to reading this marker. A PR without it can't be matched on the fallback path.
153
153
 
154
- Read the URL with `asrt get-link` and pass it to `gh pr create` so it lands in the body don't paste a URL from memory:
154
+ `asrt get-link` prints the marker as an HTML comment:
155
+
156
+ ```
157
+ <!-- assertion-session: https://app.tryassertion.com/sessions/<id> -->
158
+ ```
159
+
160
+ GitHub does not render HTML comments, so the marker stays out of the visible description but is delivered to the bot in the webhook payload. Do not paste the bare URL into the visible description — embed the marker via the command below so the format stays exact and machine-parseable:
155
161
 
156
162
  ```
157
- SESSION_URL=$(asrt get-link)
158
163
  gh pr create --title "<title>" --body "$(cat <<EOF
159
164
  <one-paragraph summary of *why*, not *what*>
160
165
 
161
- **Assertion verification:** $SESSION_URL
166
+ $(asrt get-link)
162
167
  EOF
163
168
  )"
164
169
  ```
165
170
 
166
- If a PR already exists for this branch, edit its body instead of opening a new one:
171
+ If a PR already exists for this branch, add the marker to its body instead of opening a new one:
167
172
 
168
173
  ```
169
174
  gh pr edit --body "$(cat <<EOF
170
175
  <existing summary>
171
176
 
172
- **Assertion verification:** $(asrt get-link)
177
+ $(asrt get-link)
173
178
  EOF
174
179
  )"
175
180
  ```
176
181
 
177
- Keep the `Assertion verification:` label line verbatim so reviewers and tooling can find the link. After creating or editing the PR, confirm the URL is actually in the rendered description with `gh pr view --json body`.
182
+ After creating or editing the PR, confirm the marker is in the raw body with `gh pr view --json body` — it won't show in the rendered description, and that's expected.
178
183
 
179
- **Do not open a PR without a clean `asrt verify` / `asrt verify-status`, and do not open one whose description omits the session URL.** Do not end a session with a failed/dirty verify unless the verification service itself is unavailable.
184
+ **Do not open a PR without a clean `asrt verify` / `asrt verify-status`, and do not open one whose body omits the session marker.** Do not end a session with a failed/dirty verify unless the verification service itself is unavailable.
180
185
 
181
186
  ---
182
187
 
@@ -190,7 +195,7 @@ asrt checkpoint "..." # subsequent checkpoints — auto-
190
195
  asrt decision --yes|--no <ckpt-id> # optional, on failed checkpoints only
191
196
  asrt verify # submit verification (non-blocking)
192
197
  asrt verify-status # one-shot poll; loop with your own sleep
193
- asrt get-link # last session URLmust go in the PR description
198
+ asrt get-link # hidden PR markerembed in the PR body (required)
194
199
  ```
195
200
 
196
201
  ## Environment
@@ -209,6 +214,6 @@ When running under a non-interactive harness (CI, benchmark runner, scripts):
209
214
  - Re-run `asrt checkpoint "<what you changed>" --json` (auto-continues the existing session).
210
215
  - Bound retries: stop after 3 attempts on the same failure mode, or when the same `reasoning` is returned twice in a row.
211
216
  4. `asrt verify --json` submits and exits with a one-line JSON `{"session_id", "url", "status": "submitted"}`. Poll `asrt verify-status --json` on your own cadence — terminal output is `{"session_id", "url", "status", "message", "summary", "screenshot_count"}` with exit `1` on `failed`, `0` otherwise. Choose the poll interval to fit your harness timeouts; do not block a single shell call on verify.
212
- 5. If the harness opens a PR, the `url` field (equivalently `asrt get-link`) is the session URL that **must** appear in the PR description — same requirement as interactive mode. Read it from the JSON rather than reconstructing it.
217
+ 5. If the harness opens a PR, embed the hidden session marker (`asrt get-link`) in the PR body — same requirement as interactive mode. The bot matches the PR to the session by branch first, then by this marker.
213
218
 
214
219
  Do not mix `--json` output with human-rendered output in the same run. Pick one mode and stick with it.
@@ -1,11 +1,19 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import re
3
4
  from pathlib import Path
4
5
 
5
6
  import pytest
6
7
  import typer
7
8
 
8
9
  from link import load_link, save_link
10
+ from main import render_pr_session_marker
11
+
12
+ # Must stay in sync with the bot-side parser in
13
+ # backend/api/v0/webhooks/router.py (_SESSION_MARKER_RE).
14
+ _BOT_MARKER_RE = re.compile(
15
+ r"assertion-session:\s*https?://\S+?/sessions/([A-Za-z0-9_-]+)"
16
+ )
9
17
 
10
18
 
11
19
  def test_save_link_writes_file(tmp_path: Path) -> None:
@@ -29,3 +37,16 @@ def test_load_link_empty_file(tmp_path: Path) -> None:
29
37
  (tmp_path / "link").write_text("", encoding="utf-8")
30
38
  with pytest.raises(typer.Exit):
31
39
  load_link(tmp_path)
40
+
41
+
42
+ def test_pr_session_marker_is_an_html_comment() -> None:
43
+ marker = render_pr_session_marker("https://app.tryassertion.com/sessions/sess-1")
44
+ assert marker.startswith("<!--") and marker.endswith("-->")
45
+
46
+
47
+ def test_pr_session_marker_is_parseable_by_the_bot() -> None:
48
+ """The marker the CLI emits must yield the session id the bot extracts."""
49
+ marker = render_pr_session_marker("https://app.tryassertion.com/sessions/abc-123")
50
+ match = _BOT_MARKER_RE.search(marker)
51
+ assert match is not None
52
+ assert match.group(1) == "abc-123"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes