From 30e49ea2f2454fc79a5c492916682dbbfcb0c55e Mon Sep 17 00:00:00 2001 From: Rafael Brandao Date: Thu, 1 Oct 2026 09:48:11 -0700 Subject: [PATCH 1/2] docs(archdev-skill): seal a PR's source groups instead of its focus ranges The code-region step now seals the groups archdev inspect regions prints, the same units archdev publish seals, so a session and the Factory agree on what a hunk's seal is: one group per semantic-group label over source hunks, one per file for the rest. A group whose content digest the previous head already sealed reuses that judgment with --carried-from; at most six groups are judged fresh per push. The bootstrap probes inspect regions and extract finalize --region, which the release carrying firstlanding #16218 and #16143 provides. --- archdev/SKILL.md | 9 +-- archdev/references/bootstrap.md | 8 ++- archdev/references/monitor.md | 113 ++++++++++++++++++++------------ archdev/scripts/bootstrap.ps1 | 7 +- archdev/scripts/bootstrap.sh | 6 +- scripts/fake-archdev | 7 +- 6 files changed, 95 insertions(+), 55 deletions(-) diff --git a/archdev/SKILL.md b/archdev/SKILL.md index 1ca0eac..2bc7f55 100644 --- a/archdev/SKILL.md +++ b/archdev/SKILL.md @@ -190,10 +190,11 @@ Three beats, one command assessments" in monitor.md. Outside Factory sessions, for every PR you pushed to this session, confirm its current head has annotations (`extract show pr.review-annotations --json`) and - store them if it does not, and confirm each focus range on that head - has a published `risk.code-region` seal (`inspect metadata - --sha ` lists them under `assessments`); publish the missing - ones (see "Focus range seals" in monitor.md). + store them if it does not, and confirm each source group of that + head (`inspect regions --sha `) has a published + `risk.code-region` seal (`inspect metadata --sha ` lists + them under `assessments` with their `region`); publish the missing + ones (see "Source group seals" in monitor.md). Every post carries human-readable text: structured posts add `--message ""` as the headline over the CLI-rendered diff --git a/archdev/references/bootstrap.md b/archdev/references/bootstrap.md index 5de56da..4b209ed 100644 --- a/archdev/references/bootstrap.md +++ b/archdev/references/bootstrap.md @@ -22,9 +22,11 @@ bypass the guide's consent steps. ## Version and login -1. `"$archdev" --version` (need 0.47.0+) and - `"$archdev" repo hook setup --help` (must include `--local`). If the - published release lacks repository setup, stop; never fall back globally. +1. `"$archdev" --version` (need 0.47.0+), + `"$archdev" repo hook setup --help` (must include `--local`), and + `"$archdev" inspect regions --help` with `extract finalize --help` + listing `--region` (the source-group seal commands). If the published + release lacks any of them, stop; never fall back globally. 2. `"$archdev" auth status`. For approved stream reporting, if unauthenticated, run `"$archdev" auth login` and keep the interactive process available while the user signs in. Do not request tokens in chat or copy another user's diff --git a/archdev/references/monitor.md b/archdev/references/monitor.md index ffec645..d629ef9 100644 --- a/archdev/references/monitor.md +++ b/archdev/references/monitor.md @@ -433,8 +433,8 @@ The flow, per event: session while `brief.json`'s digest is unchanged. `` is the resource being judged, never the event name: `task` for every `task.*` event, `plan` for `plan.*`, `pr` for `pr.*` (the table under - Report). `code-region` grades one changed range and is published per - focus range instead of posted (Focus range seals, below). + Report). `code-region` grades one source group of a head and is + published per group instead of posted (Source group seals, below). 2. **Judgment.** Author one JSON file with `input` and `assessment` matching the two schemas in the brief. - `input.subject.source.source` names the event subject exactly: @@ -555,7 +555,7 @@ moment you post it. A `pr.updated` after a push gets a fresh assessment of the new head; the CLI checks only that the seal names the same PR, not which head it graded, so re-assessing is on you. For a PR, store its review annotations first (next section), publish a seal for each -focus range (the section after), then assess the PR and post. +source group (the section after), then assess the PR and post. Not yours to run: @@ -614,7 +614,7 @@ its branch): 5. Confirm with `"$archdev" extract show pr.review-annotations --json`: it prints the stored row; `ExtractionNotFoundError` means nothing is stored for this head; any other error means the checkout - is not at the PR head. Then publish the focus range seals (next + is not at the PR head. Then publish the source group seals (next section) and log the `pr.*` event. Verify before you stop: at every stopping point, and before any `done` @@ -629,7 +629,7 @@ no GitHub origin; a validation error), fix what it names or say so in the event's `--message` and in your reply to the user; never skip silently. -## Focus range seals +## Source group seals ArchDev grades a hunk from the sealed `risk.code-region` assessment that covers it: the rail card, the callout, the toolbar badge, the risk @@ -640,50 +640,77 @@ are rows in `github_pr_risk_assessments` for the exact head, so they vanish on every push exactly as annotations do, and the same session that stores the annotations publishes them. -Right after the annotation row is stored (previous section, step 5), -for each range in the row's `summary.focus`, from the checkout at the -PR head: +The unit sealed is a source group, not a focus range: one group per +semantic-group label in the head's annotation row over its source +hunks, plus one group per file for the source hunks no label covers. +Test, documentation, lockfile and generated paths never form a group. +`archdev publish` seals the same groups the same way for the heads it +pushes, so a session and the Factory agree on what a hunk's seal is. -1. **Collect.** `"$archdev" extract context code-region.risk +Right after the annotation row is stored (previous section, step 5), +from the checkout at the PR head: + +1. **List the groups.** `"$archdev" --json inspect regions + #` prints `groups` in seal order (gravest risk + annotation first, then diff order). Each carries `label`, + `locations` (changed ranges on one side, or a nontext file), + `content_sha256` (the group's identity across pushes), and `region`, + the exact `--region` value for step 4. Without a stored annotation + row it groups by file and says so; a row authored against a + different diff is refused, so store the row for this head first. +2. **Reuse what the previous head sealed.** When this push replaced a + head you sealed earlier, `"$archdev" --json inspect metadata + --sha ` lists its seals with their `region`. A + previous `risk.code-region` seal whose `region.content_sha256` + equals a group's `content_sha256` is that group's judgment: collect + the group as in step 3, take `assessment` from the previous seal's + `result.assessment` instead of judging again, and pass + `--carried-from :` in step 4. If + finalize refuses the carry (a cited evidence id no longer resolves + in the new packet), judge the group fresh. +3. **Collect.** `"$archdev" extract context code-region.risk "#;::-" --json` freezes the - range and collects its evidence (the diff at the head, the edited - symbols and their callers, checks). The range must be changed lines - only, on one side; the collector refuses a selection that includes - unchanged lines, so split a focus range around context and collect - each changed run, or select several changed ranges of one behavior - in one call by repeating `;::-`; a nontext - file (an image, a binary) is selected whole with `;file=`. The - `user` string is a JSON object whose `input` is the complete packet, - with `subject.locations` already set. -2. **Judge.** Author `{input, assessment}` as in Risk assessments step - 2, with `input` taken from the collected packet: keep `subject` as - collected (its `source.source` is the pull request URL, which - `--publish` accepts), keep the evidence items you cite with their - ids and kinds, add what you observed yourself, and carry the - collector's `missingInputs` forward. `--publish` stores the whole - seal in the row, so a full collected packet fits here; the 64 KB cap - applies to `log post` attachments only. Grade the range, not the PR: - `objective` and `scope` name the behavior the range changes. -3. **Seal and publish.** `"$archdev" extract finalize risk.code-region - ./judgment.json --out ./sealed/-/ --publish #` - validates, derives the combined grade, writes `result.json` and - `digest.txt`, and stores the row for `input.subject.head`. The - result's `published` block echoes `head_sha`, `combined_risk` and - `locations`. A seal whose subject names another pull request, or a - `risk.pr` seal, is refused; a repeat of the same seal finds its row - and exits 0. A store failure exits non-zero: fix what it names - (signed out, wrong pull) or say so in the `pr.*` event's `--message`. -4. **Mitigate, then recompute**, as in Risk assessments step 4: a - medium or high grade on a range you can make safer within the PR's + group's ranges and collects their evidence (the diff at the head, + the edited symbols and their callers, checks). Build the selector + from the group's `locations`: repeat `;::-` + for every `lines` location, and `;file=` for a `file` + location. Every range is changed lines only, which the collector + requires. The `user` string is a JSON object whose `input` is the + complete packet, with `subject.locations` already set. +4. **Judge, seal and publish.** Author `{input, assessment}` as in Risk + assessments step 2, with `input` taken from the collected packet: + keep `subject` as collected (its `source.source` is the pull + request URL, which `--publish` accepts), keep the evidence items you + cite with their ids and kinds, add what you observed yourself, and + carry the collector's `missingInputs` forward. Grade the group, not + the PR: `objective` and `scope` name the behavior the group changes. + Then `"$archdev" extract finalize risk.code-region ./judgment.json + --out ./sealed/-/ --publish # --region + ""`, plus `--carried-from` for a reused + judgment. The row records the group's identity and provenance beside + the seal, so the next push finds it. A seal whose subject names + another pull request, or a `risk.pr` seal, is refused; a repeat of + the same seal finds its row and exits 0. A store failure exits + non-zero: fix what it names (signed out, wrong pull, a carried-from + the earlier head does not hold) or say so in the `pr.*` event's + `--message`. +5. **Cap.** Judge at most six groups fresh per push, in the printed + order; carried seals do not count. Seal the rest on the next push, + where the already sealed groups carry forward and the cap goes to + the ones still missing. Say in the `pr.*` event's `--message` which + groups are unsealed. +6. **Mitigate, then recompute**, as in Risk assessments step 4: a + medium or high grade on a group you can make safer within the PR's scope is a fix and a push, which is a new head, so go back to the - annotation row for that head and publish its seals afresh. At most - two rounds. + annotation row for that head and publish its seals afresh; the + groups you did not touch carry forward. At most two rounds. Verify with `"$archdev" inspect metadata --sha --json`: `assessments` lists every stored seal for the head with its -`definition_id`, `combined_risk`, `locations` and `producer`. Every -focus range should have one covering seal; a range without one shows -the producer's unsealed label in the review. +`definition_id`, `combined_risk`, `locations`, `region`, `carried_from` +and `producer`. Every group `inspect regions` prints should have a seal +whose `region.content_sha256` matches; a group without one shows the +producer's unsealed label on its hunks in the review. ## Factory sessions diff --git a/archdev/scripts/bootstrap.ps1 b/archdev/scripts/bootstrap.ps1 index 8602b86..8c728ef 100644 --- a/archdev/scripts/bootstrap.ps1 +++ b/archdev/scripts/bootstrap.ps1 @@ -58,12 +58,15 @@ function Test-Skill([string]$Binary) { if ($LASTEXITCODE -ne 0 -or (($helpText -join "`n") -notmatch "--project ")) { return $false } $helpText = & $Binary extract finalize --help 2>$null if ($LASTEXITCODE -ne 0 -or (($helpText -join "`n") -notmatch "--publish ")) { return $false } + if (($helpText -join "`n") -notmatch "--region ") { return $false } + $helpText = & $Binary inspect regions --help 2>$null + if ($LASTEXITCODE -ne 0 -or (($helpText -join "`n") -notmatch "Usage: archdev inspect regions ")) { return $false } $helpText = & $Binary repo hook setup --help 2>$null return ($LASTEXITCODE -eq 0 -and (($helpText -join "`n") -match "--local")) } if (-not (Test-Skill $archdev)) { - [Console]::Error.WriteLine("Updating ArchDev: this skill requires 0.47.0+ and repository hook setup with --local.") + [Console]::Error.WriteLine("Updating ArchDev: this skill requires 0.47.0+, repository hook setup with --local, and the source-group seal commands (inspect regions, extract finalize --region).") $archdev = Install-ArchDev } @@ -72,7 +75,7 @@ if (-not (Test-Path -LiteralPath $archdev -PathType Leaf)) { } & $archdev --version *> $null if ($LASTEXITCODE -ne 0) { throw "ArchDev version verification failed" } -if (-not (Test-Skill $archdev)) { throw "Installed ArchDev lacks required commands or --local hook setup (need 0.47.0+); stopping without a global fallback" } +if (-not (Test-Skill $archdev)) { throw "Installed ArchDev lacks required commands, --local hook setup, or the source-group seal commands (inspect regions, extract finalize --region); stopping without a global fallback" } # Resolving the executable must not choose configuration scope. Install and # repair hooks only through the approved branch in https://archdev.ai/install.md. diff --git a/archdev/scripts/bootstrap.sh b/archdev/scripts/bootstrap.sh index 78674a9..398a9a1 100755 --- a/archdev/scripts/bootstrap.sh +++ b/archdev/scripts/bootstrap.sh @@ -83,11 +83,13 @@ supports_skill() { "$1" projects list --help 2>/dev/null | grep -F "Usage: archdev projects list " >/dev/null && "$1" log post --help 2>/dev/null | grep -F -- "--project " >/dev/null && "$1" extract finalize --help 2>/dev/null | grep -F -- "--publish " >/dev/null && + "$1" extract finalize --help 2>/dev/null | grep -F -- "--region " >/dev/null && + "$1" inspect regions --help 2>/dev/null | grep -F "Usage: archdev inspect regions " >/dev/null && "$1" repo hook setup --help 2>/dev/null | grep -F -- "--local" >/dev/null } if ! supports_skill "$executable"; then - printf 'Updating ArchDev: this skill requires 0.47.0+ and repository hook setup with --local.\n' >&2 + printf 'Updating ArchDev: this skill requires 0.47.0+, repository hook setup with --local, and the source-group seal commands (inspect regions, extract finalize --region).\n' >&2 install_archdev || exit 1 executable="$(absolute_path "$install_dir/archdev")" fi @@ -99,7 +101,7 @@ fi "$executable" --version >&2 supports_skill "$executable" || { - printf 'Installed ArchDev lacks required commands or --local hook setup (need 0.47.0+); stopping without a global fallback.\n' >&2 + printf 'Installed ArchDev lacks required commands, --local hook setup, or the source-group seal commands (inspect regions, extract finalize --region); stopping without a global fallback.\n' >&2 exit 1 } diff --git a/scripts/fake-archdev b/scripts/fake-archdev index 3352785..c06a541 100755 --- a/scripts/fake-archdev +++ b/scripts/fake-archdev @@ -16,7 +16,12 @@ case "$args" in "repo status --help") echo "Probe CLI, login, model access, repo wiring, taxonomy, and hooks" ;; "projects list --help") echo "Usage: archdev projects list [options]" ;; "log post --help") echo " --project Project for this post" ;; - "extract finalize --help") echo " --publish Publish to a pull request" ;; + "extract finalize --help") + echo " --publish Publish to a pull request" + echo " --region Record the source group the seal was judged for" + echo " --carried-from Record the earlier head's seal the judgment reuses" + ;; + "inspect regions --help") echo "Usage: archdev inspect regions [options] " ;; "repo hook setup --help") [[ "${ARCHDEV_FAKE_NO_LOCAL:-0}" == 1 ]] || echo " --local Install repository hooks" echo " --refresh Only update harnesses that already have archdev hooks" From 3b4f78f112feb9bed03c5d12161664eb194f221a Mon Sep 17 00:00:00 2001 From: Rafael Brandao Date: Thu, 1 Oct 2026 09:52:53 -0700 Subject: [PATCH 2/2] docs(archdev-skill): name the source-group seal commands in the requirement line --- archdev/SKILL.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/archdev/SKILL.md b/archdev/SKILL.md index 2bc7f55..e82a44f 100644 --- a/archdev/SKILL.md +++ b/archdev/SKILL.md @@ -7,8 +7,9 @@ description: Core ArchDev workflow — use for anything involving ArchDev. Cover Requires CLI 0.47.0 or newer (the `repo` namespace, `log post` / `messages` / `search`, harness hooks, `extract brief`, `extract finalize` -with `--publish` for sealed code-region assessments on a PR's focus -ranges, and `log --assessment` for sealed risk assessments on +with `--publish`, `--region` and `--carried-from` for sealed code-region +assessments on a PR's source groups, `inspect regions` to list those +groups, and `log --assessment` for sealed risk assessments on plan/task/pr events, plus `projects`, `log post --project`, hooks that keep an `--uninstall` opt-out, and the Stop hook that holds a session once for a pushed pull request head with no review annotations). Hook setup