assertion-cli 0.5.1__tar.gz → 0.5.3__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.
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/PKG-INFO +1 -1
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/assertion_cli.egg-info/PKG-INFO +1 -1
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/git.py +2 -1
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/main.py +23 -2
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/pyproject.toml +1 -1
- assertion_cli-0.5.3/templates/ACTIVATION.md +50 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/templates/SKILL.md +29 -16
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_git.py +33 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_link.py +21 -0
- assertion_cli-0.5.1/templates/ACTIVATION.md +0 -21
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/README.md +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/api.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/assertion_cli.egg-info/SOURCES.txt +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/assertion_cli.egg-info/dependency_links.txt +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/assertion_cli.egg-info/entry_points.txt +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/assertion_cli.egg-info/requires.txt +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/assertion_cli.egg-info/top_level.txt +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/bundle.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/link.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/models.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/session.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/setup.cfg +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/templates/__init__.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_api.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_bundle.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_decision.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_init.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_main.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_prompt.py +0 -0
- {assertion_cli-0.5.1 → assertion_cli-0.5.3}/tests/test_session.py +0 -0
|
@@ -120,6 +120,7 @@ def get_uncommitted_diff(repo_root: Path, base_sha: str) -> str:
|
|
|
120
120
|
]
|
|
121
121
|
|
|
122
122
|
parts = [p for p in [tracked, "\n".join(untracked_diffs)] if p]
|
|
123
|
-
|
|
123
|
+
diff = "\n".join(parts)
|
|
124
|
+
return diff + "\n" if diff else diff
|
|
124
125
|
except RuntimeError as exc:
|
|
125
126
|
exit_with_error(f"Failed to collect git diff: {exc}")
|
|
@@ -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
|
|
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")
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Assertion verification
|
|
2
|
+
|
|
3
|
+
This repo uses the Assertion CLI (`asrt`) to track user intent and verify your work. The full workflow lives in the `assertion-cli` skill:
|
|
4
|
+
|
|
5
|
+
- **Claude Code** — [`.claude/skills/assertion-cli/SKILL.md`](.claude/skills/assertion-cli/SKILL.md)
|
|
6
|
+
- **Codex / Cursor** — [`.agents/skills/assertion-cli/SKILL.md`](.agents/skills/assertion-cli/SKILL.md)
|
|
7
|
+
|
|
8
|
+
Both files are byte-identical. Read whichever your agent loads (or either one directly). In brief, follow these three rules for every conversation:
|
|
9
|
+
|
|
10
|
+
1. **Log every user message:** run `asrt prompt "<exact text>"` before anything else, on every turn — it's the verifier's record of intent.
|
|
11
|
+
2. **Checkpoint at trajectory-feedback moments**, not every change. First checkpoint: `asrt stacks`, pick the stack that fits, then `asrt checkpoint --stack <id> "<summary>"`; later ones drop `--stack` and auto-continue. A feature build is a handful of checkpoints.
|
|
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 that PR **must** carry the hidden Assertion session marker (see below).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## ⚠️ REQUIRED: every PR must embed the hidden session marker
|
|
17
|
+
|
|
18
|
+
**This is the single most-missed step, and it is not optional.** A PR opened from an Assertion session that omits the marker cannot be linked back to its verification, so the work reads as unverified.
|
|
19
|
+
|
|
20
|
+
The Assertion GitHub bot links a PR to its verification session by **branch name first**. When the branch name doesn't match the one you verified on (you renamed it, the head ref differs, etc.), the bot falls back to reading the marker. No marker → no fallback → no link.
|
|
21
|
+
|
|
22
|
+
`asrt get-link` prints the marker as an HTML comment that GitHub hides from the rendered description but still delivers to the bot in the webhook payload:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
<!-- assertion-session: https://app.tryassertion.com/sessions/<id> -->
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Open the PR with the marker embedded** — never paste the bare URL into the visible body; use the command so the format stays exact:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
gh pr create --title "<title>" --body "$(printf '%s\n\n%s\n' '<one-paragraph why>' "$(asrt get-link)")"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If a PR already exists for the branch, add the marker instead of opening a new one:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
gh pr edit --body "$(printf '%s\n\n%s\n' '<existing summary>' "$(asrt get-link)")"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Then confirm it landed.** The marker won't show in the rendered description — that's expected — so verify it's in the raw body:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
gh pr view --json body --jq .body | grep -q 'assertion-session:' && echo "marker present" || echo "MARKER MISSING — fix before continuing"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Hard gates (do not bypass)
|
|
49
|
+
- **No PR whose body omits the session marker.** If `asrt get-link` has nothing to return, you haven't verified yet — go back to rule 3.
|
|
50
|
+
- **Confirm the marker after creating/editing the PR** with the `gh pr view` check above. Treat a missing marker as a blocking error, not a warning.
|
|
@@ -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
|
|
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
|
|
@@ -16,6 +16,8 @@ Before any `asrt` call:
|
|
|
16
16
|
- You are inside a git repository.
|
|
17
17
|
- `asrt init` has been run in this repo. It records the current HEAD as the diff base that every checkpoint/verify diffs against, and installs the skill files you are reading right now. If `asrt checkpoint` or `asrt verify` errors with "No diff base recorded", run `asrt init` and retry.
|
|
18
18
|
|
|
19
|
+
**Starting a fresh session:** when beginning a new session, delete the contents of `.assertion/` first. This clears the previous session's in-flight state (metadata, prompts log, link) so a new session starts clean and anchors to the stack you pick on the first checkpoint. Only the user should do this — it resets the session.
|
|
20
|
+
|
|
19
21
|
Treat `.assertion/metadata.json`, `.assertion/prompts`, and `.assertion/base_sha` as internal state owned by the CLI. Do not create, edit, or delete those files manually — use `asrt prompt` to append to the prompts log.
|
|
20
22
|
|
|
21
23
|
`asrt stacks` is read-only and lists every verification stack in the user's workspace, along with the repo each is configured for. Run it once per session before your first checkpoint so you can pick a stack ID; do not hardcode IDs from memory.
|
|
@@ -137,46 +139,59 @@ done
|
|
|
137
139
|
|
|
138
140
|
`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
141
|
|
|
140
|
-
`asrt get-link` prints the
|
|
142
|
+
`asrt get-link` prints the hidden PR marker — an 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
143
|
|
|
142
144
|
**After status reports terminal, branch on the outcome:**
|
|
143
145
|
|
|
144
146
|
| Outcome | What you do next |
|
|
145
147
|
|---|---|
|
|
146
|
-
| **Clean** (succeeded, no required changes) | Open a PR and **
|
|
148
|
+
| **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
149
|
| **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
150
|
| **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
151
|
|
|
150
|
-
###
|
|
152
|
+
### Embed the hidden session marker in the PR (required)
|
|
153
|
+
|
|
154
|
+
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.
|
|
155
|
+
|
|
156
|
+
`asrt get-link` prints the marker as an HTML comment:
|
|
151
157
|
|
|
152
|
-
|
|
158
|
+
```
|
|
159
|
+
<!-- assertion-session: https://app.tryassertion.com/sessions/<id> -->
|
|
160
|
+
```
|
|
153
161
|
|
|
154
|
-
|
|
162
|
+
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
163
|
|
|
156
164
|
```
|
|
157
|
-
SESSION_URL=$(asrt get-link)
|
|
158
165
|
gh pr create --title "<title>" --body "$(cat <<EOF
|
|
159
166
|
<one-paragraph summary of *why*, not *what*>
|
|
160
167
|
|
|
161
|
-
|
|
168
|
+
$(asrt get-link)
|
|
162
169
|
EOF
|
|
163
170
|
)"
|
|
164
171
|
```
|
|
165
172
|
|
|
166
|
-
If a PR already exists for this branch,
|
|
173
|
+
If a PR already exists for this branch, add the marker to its body instead of opening a new one:
|
|
167
174
|
|
|
168
175
|
```
|
|
169
176
|
gh pr edit --body "$(cat <<EOF
|
|
170
177
|
<existing summary>
|
|
171
178
|
|
|
172
|
-
|
|
179
|
+
$(asrt get-link)
|
|
173
180
|
EOF
|
|
174
181
|
)"
|
|
175
182
|
```
|
|
176
183
|
|
|
177
|
-
|
|
184
|
+
**Enforce it — don't assume it landed.** Immediately after creating or editing the PR, confirm the marker is in the raw body (it won't show in the rendered description — that's expected):
|
|
178
185
|
|
|
179
|
-
|
|
186
|
+
```
|
|
187
|
+
gh pr view --json body --jq .body | grep -q 'assertion-session:' \
|
|
188
|
+
&& echo "marker present" \
|
|
189
|
+
|| { echo "MARKER MISSING — re-run gh pr edit with \$(asrt get-link) before continuing"; exit 1; }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
A missing marker is a **blocking error**, not a warning: do not consider the PR step complete, and do not move on, until this check prints `marker present`. Re-run `gh pr edit` with `$(asrt get-link)` and re-check until it passes.
|
|
193
|
+
|
|
194
|
+
**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
195
|
|
|
181
196
|
---
|
|
182
197
|
|
|
@@ -190,13 +205,11 @@ asrt checkpoint "..." # subsequent checkpoints — auto-
|
|
|
190
205
|
asrt decision --yes|--no <ckpt-id> # optional, on failed checkpoints only
|
|
191
206
|
asrt verify # submit verification (non-blocking)
|
|
192
207
|
asrt verify-status # one-shot poll; loop with your own sleep
|
|
193
|
-
asrt get-link #
|
|
208
|
+
asrt get-link # hidden PR marker — embed in the PR body (required)
|
|
194
209
|
```
|
|
195
210
|
|
|
196
211
|
## Environment
|
|
197
212
|
|
|
198
|
-
- `ASSERTION_BASE_URL` — point the CLI at a non-default backend (default `http://localhost:8000`).
|
|
199
|
-
|
|
200
213
|
## Non-interactive / harness mode
|
|
201
214
|
|
|
202
215
|
When running under a non-interactive harness (CI, benchmark runner, scripts):
|
|
@@ -209,6 +222,6 @@ When running under a non-interactive harness (CI, benchmark runner, scripts):
|
|
|
209
222
|
- Re-run `asrt checkpoint "<what you changed>" --json` (auto-continues the existing session).
|
|
210
223
|
- Bound retries: stop after 3 attempts on the same failure mode, or when the same `reasoning` is returned twice in a row.
|
|
211
224
|
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
|
|
225
|
+
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
226
|
|
|
214
227
|
Do not mix `--json` output with human-rendered output in the same run. Pick one mode and stick with it.
|
|
@@ -222,3 +222,36 @@ def test_get_uncommitted_diff_includes_local_only_commit_against_base(
|
|
|
222
222
|
diff = get_uncommitted_diff(tmp_path, base_sha)
|
|
223
223
|
assert "local.txt" in diff
|
|
224
224
|
assert "+local change" in diff
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# --- trailing newline (diff must never be corrupt for git apply) ---
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def test_get_uncommitted_diff_ends_with_newline_when_not_empty(tmp_path: Path) -> None:
|
|
231
|
+
"""Diff must end with \\n so git apply on the receiving end never chokes."""
|
|
232
|
+
_init_repo_with_commit(tmp_path)
|
|
233
|
+
|
|
234
|
+
# Tracked change
|
|
235
|
+
f = tmp_path / "file.txt"
|
|
236
|
+
f.write_text("content\n")
|
|
237
|
+
subprocess.run(
|
|
238
|
+
["git", "add", "file.txt"], cwd=tmp_path, capture_output=True, check=True
|
|
239
|
+
)
|
|
240
|
+
subprocess.run(
|
|
241
|
+
["git", "commit", "-m", "add file"],
|
|
242
|
+
cwd=tmp_path,
|
|
243
|
+
capture_output=True,
|
|
244
|
+
check=True,
|
|
245
|
+
env={**GIT_ENV, "HOME": str(tmp_path)},
|
|
246
|
+
)
|
|
247
|
+
f.write_text("modified\n")
|
|
248
|
+
|
|
249
|
+
diff = get_uncommitted_diff(tmp_path, "HEAD")
|
|
250
|
+
assert diff != ""
|
|
251
|
+
assert diff.endswith("\n"), f"tracked diff should end with newline, got: {diff[-10:]!r}"
|
|
252
|
+
|
|
253
|
+
# Untracked only
|
|
254
|
+
(tmp_path / "untracked.py").write_text("x = 1\n")
|
|
255
|
+
diff2 = get_uncommitted_diff(tmp_path, "HEAD")
|
|
256
|
+
assert diff2 != ""
|
|
257
|
+
assert diff2.endswith("\n"), f"untracked diff should end with newline, got: {diff2[-10:]!r}"
|
|
@@ -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"
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Assertion verification
|
|
2
|
-
|
|
3
|
-
This repo uses the Assertion CLI (`asrt`) to track user intent and verify your work. The full workflow lives in the `assertion-cli` skill:
|
|
4
|
-
|
|
5
|
-
- **Claude Code** — [`.claude/skills/assertion-cli/SKILL.md`](.claude/skills/assertion-cli/SKILL.md)
|
|
6
|
-
- **Codex / Cursor** — [`.agents/skills/assertion-cli/SKILL.md`](.agents/skills/assertion-cli/SKILL.md)
|
|
7
|
-
|
|
8
|
-
Both files are byte-identical. Read whichever your agent loads (or either one directly). In brief, follow these three rules for every conversation:
|
|
9
|
-
|
|
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
|
-
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:
|
|
13
|
-
|
|
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")"
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
If a PR already exists for the branch, add the line with `gh pr edit --body` instead of opening a new one.
|
|
20
|
-
|
|
21
|
-
Do not open a PR without a clean `asrt verify`, and do not open one whose description omits the session URL.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|