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
32 changes: 32 additions & 0 deletions .changeset/activation-reconciliation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
"@bradygaster/squad-sdk": patch
---

Validate real numeric task and epic issue references and add an explicit activation
reader for independently verified current-state-authorized reconciliations.
Preserve valid legacy activation records while rejecting ambiguous, malformed,
or unverified replacements without rewriting historical acceptance.
Require exactly one matching verifier evidence record and bind any selected
phase scope to its canonical, independently verified phase IDs.
Require activation-source phases to exactly match verifier evidence, rejecting
internally inconsistent caller-supplied evidence without changing verifier trust.
Reject malformed legacy phase scopes with non-positive, unsafe, nonnumeric, or
duplicate phase IDs consistently with the packaged activation checker.
Allow a verifier-supplied full frozen-plan assignment context to validate complete
epic identity sets across phase subsets; retain strict exact-row validation when
that independent context is absent.
Normalize verifier and producer display names consistently with trim/lowercase
while retaining exact stable agent identity checks.
Reject task issues that collide with the origin or any epic issue, and prevent
non-origin epics from reusing the origin issue.
Support explicit verifier-authorized pending-source reconciliation with matching
capture metadata, frozen plan and registry digests, and phase scope. Pending
reservations and their prior references never authorize activation on their own.
Select complete transitive phase histories only when every reconciliation has an
independent verifier proof and exact source links form one fully consumed chain
with consistent frozen snapshots, expanding phases, and preserved prior mappings.
Ignore unrelated discussion in scoped pairs and complete histories while retaining
rejection of extra activation or pending candidates and ambiguous chains.
Require a nonempty, strictly shorter positional phase prefix across ancestors;
reject whole-plan phase expansion and explicitly selected phases absent from the
frozen plan without requiring consecutive phase IDs.
28 changes: 10 additions & 18 deletions .github/workflows/squad-agent-binding-check.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Squad Agent Binding Check

on:
workflow_dispatch:
workflow_run:
# "Squad" is the installed gh-aw workflow; "Squad CI" keeps this source
# repository's checker wired to a workflow that exists here.
Expand All @@ -13,37 +14,28 @@ permissions:

jobs:
check:
name: Historical bindings (not current-run completion)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 #v6
with:
node-version: 22
- name: Collect activation evidence from the completed run
- name: Collect historical activation records (not run outputs)
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 #v9
with:
script: |
const fs = require('node:fs');
const started = new Date(context.payload.workflow_run.run_started_at);
const completed = new Date(context.payload.workflow_run.updated_at);
const comments = await github.paginate(github.rest.issues.listCommentsForRepo, {
...context.repo,
since: started.toISOString(),
per_page: 100,
});
const activationComments = comments
.filter(comment => new Date(comment.created_at) <= completed)
.filter(comment => /Structured data:/i.test(comment.body ?? '')
&& /"squad_artifact"\s*:\s*"?(?:phases-activated|activated|phases-accepted|plan-accepted)/i.test(comment.body ?? ''))
.map(comment => ({
body: comment.body,
issue: Number(comment.issue_url.split('/').at(-1)),
}));
const { pathToFileURL } = require('node:url');
const { join } = require('node:path');
const { collectHistoricalActivationRecords } = await import(pathToFileURL(
join(process.env.GITHUB_WORKSPACE, 'workflows/shared/check-agent-binding.mjs')).href);
const audit = await collectHistoricalActivationRecords({ github, context });
fs.writeFileSync(
`${process.env.RUNNER_TEMP}/activation-comments.json`,
JSON.stringify(activationComments),
JSON.stringify(audit),
);
- name: Check agent bindings
- name: Audit historical bindings without asserting current-run completion
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/squad-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,8 @@ jobs:
--source-revision "$SQUAD_SOURCE_REVISION"
node .github/workflows/shared/squad-install-verifier.mjs --materialize-runtime
test "$(find .github/workflows -maxdepth 1 -name 'squad*.md' | wc -l | tr -d ' ')" = 8
test "$(find .github/workflows/shared -type f ! -name 'squad-bootstrap-trigger-probe.json' | wc -l | tr -d ' ')" = 17
test "$(find .github/workflows/shared -type f ! -name 'squad-bootstrap-trigger-probe.json' | wc -l | tr -d ' ')" = 19
test -f .github/workflows/squad-agent-binding-check.yml
test "$(find .github/skills/gh-aw-enlistment -type f | wc -l | tr -d ' ')" = 1
node --input-type=module -e '
import { compileWithPinnedActions } from "./.github/workflows/shared/squad-install-verifier.mjs";
Expand Down
Loading
Loading