Skip to content

Define stable Squad agent identity provenance - #2066

Merged
bradygaster merged 20 commits into
devfrom
bradygaster-agent-identity-producer
Sep 22, 2026
Merged

bradygaster merged 20 commits into
devfrom
bradygaster-agent-identity-producer

Conversation

@bradygaster

Copy link
Copy Markdown
Collaborator

Summary

  • version .squad/casting/registry.json as the producer-owned squad-agent-provenance/v1 contract
  • preserve immutable agent IDs across rename/recast, tombstone retirements, reject collisions and malformed/partial producer state
  • add optional repository-path avatar references, SDK parser/reconciler APIs, CLI/preset/GH-AW producer wiring, fixtures, contract tests, and consumer semantics documentation

Consumer contract

Squadcaster should use the registry object key as stable agent ID and display_name for presentation. persistent_name remains an equal compatibility alias. Missing or malformed provenance means identity is unavailable; do not infer from owner, assignee, author, reviewer, actor, branch, or roster display. Optional avatars require a separate repository content fetch and must remain under .squad/agents/{id}/.

Validation

  • full build passed
  • type-check and ESLint passed
  • focused provenance/bootstrap/GH-AW suites passed (281 tests)
  • full suite: 9,078 passed; remaining failures are pre-existing worktree/external-state, timing, and compiled-artifact baselines, except the two provenance bootstrap fixtures fixed in this PR

Refs bradygaster/squadcaster#45

Copilot AI lite review requested due to automatic review settings September 21, 2026 22:01
@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit d40250a

PR Scope: 📦🔧 Mixed (product + infrastructure)

⚠️ 3 item(s) to address before review

Status Check Details
❌ Single commit 20 commits — consider squashing before review
✅ Not in draft Ready for review
❌ Branch up to date dev is 6 commit(s) ahead — rebase recommended
❌ Copilot review No Copilot review yet — it may still be processing
✅ Changeset present Changeset file found
✅ Scope clean ⚠️ PR includes 1 .squad/ file(s) — ensure these are intentional
✅ No merge conflicts No merge conflicts
✅ Copilot threads resolved 0 active Copilot thread(s) resolved (2 outdated skipped)
✅ CI passing All checks passing

Files Changed (53 files, +9030 −481)

File +/−
.changeset/agent-identity-provenance.md +25 −0
.changeset/reject-legacy-revision-tokens.md +5 −0
.changeset/strict-casting-durability.md +6 −0
.changeset/strict-casting-readers.md +5 −0
.squad-templates/casting-registry.json +4 −0
.squad/casting/registry.json +22 −18
docs/src/content/docs/concepts/agent-identity-provenance.md +188 −0
docs/src/navigation.ts +1 −0
packages/squad-cli/src/cli/commands/doctor.ts +10 −4
packages/squad-cli/src/cli/commands/export.ts +8 −7
packages/squad-cli/src/cli/commands/health.ts +4 −5
packages/squad-cli/src/cli/commands/import.ts +92 −20
packages/squad-cli/src/cli/core/cast.ts +189 −50
packages/squad-cli/src/cli/core/upgrade.ts +43 −30
packages/squad-cli/templates/casting-registry.json +4 −0
packages/squad-sdk/src/casting/agent-provenance.ts +704 −0
packages/squad-sdk/src/casting/durable-registry.ts +1498 −0
packages/squad-sdk/src/casting/index.ts +55 −11
packages/squad-sdk/src/config/init.ts +40 −19
packages/squad-sdk/src/config/team-capabilities.ts +35 −15
packages/squad-sdk/src/presets/index.ts +291 −72
packages/squad-sdk/src/presets/scaffold.ts +373 −80
packages/squad-sdk/src/tools/index.ts +1 −3
packages/squad-sdk/templates/casting-registry.json +4 −0
scripts/check-agent-binding.mjs +361 −6
scripts/validate-gh-aw-cast.mjs +289 −7
templates/casting-registry.json +4 −0
test/agent-provenance.test.ts +498 −0
test/cast-parser.test.ts +122 −1
test/casting-durable-registry.test.ts +970 −0
test/casting-registry-template.test.ts +34 −0
test/casting.test.ts +76 −1
test/check-agent-binding.test.ts +89 −2
test/cli/doctor.test.ts +28 −1
test/cli/export-import.test.ts +203 −8
test/cli/health-command.test.ts +79 −9
test/cli/init-upgrade-parity.test.ts +20 −2
test/cli/state-mcp.test.ts +11 −7
test/cli/upgrade.test.ts +30 −9
test/fixtures/agent-provenance/cases.json +232 −0
test/gh-aw-activation-artifact-integrity.test.ts +166 −2
test/gh-aw-bootstrap-workflow.test.ts +50 −2
test/gh-aw-cast-validator.test.ts +447 −4
test/gh-aw-quality.test.ts +4 −2
test/init-scaffolding.test.ts +10 −8
test/init-sdk.test.ts +3 −3
test/presets.test.ts +1142 −2
test/state-backend.test.ts +15 −9
test/team-capabilities-lifecycle.test.ts +153 −5
test/template-sync.test.ts +53 −27
... +3 more files

Total: +9030 −481


This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

🔴 Impact Analysis — PR #2066

Risk tier: 🔴 CRITICAL

📊 Summary

Metric Count
Files changed 53
Files added 11
Files modified 42
Files deleted 0
Modules touched 8
Critical files 3

🎯 Risk Factors

  • 53 files changed (>50 → CRITICAL)
  • 8 modules touched (5-8 → HIGH)
  • Critical files touched: packages/squad-sdk/src/casting/index.ts, packages/squad-sdk/src/presets/index.ts, packages/squad-sdk/src/tools/index.ts

📦 Modules Affected

docs (2 files)
  • docs/src/content/docs/concepts/agent-identity-provenance.md
  • docs/src/navigation.ts
root (8 files)
  • .changeset/agent-identity-provenance.md
  • .changeset/reject-legacy-revision-tokens.md
  • .changeset/strict-casting-durability.md
  • .changeset/strict-casting-readers.md
  • templates/casting-registry.json
  • workflows/shared/squad-cast-validator.mjs
  • workflows/squad-bootstrap.md
  • workflows/squad.md
scripts (2 files)
  • scripts/check-agent-binding.mjs
  • scripts/validate-gh-aw-cast.mjs
squad-cli (7 files)
  • packages/squad-cli/src/cli/commands/doctor.ts
  • packages/squad-cli/src/cli/commands/export.ts
  • packages/squad-cli/src/cli/commands/health.ts
  • packages/squad-cli/src/cli/commands/import.ts
  • packages/squad-cli/src/cli/core/cast.ts
  • packages/squad-cli/src/cli/core/upgrade.ts
  • packages/squad-cli/templates/casting-registry.json
squad-sdk (9 files)
  • packages/squad-sdk/src/casting/agent-provenance.ts
  • packages/squad-sdk/src/casting/durable-registry.ts
  • packages/squad-sdk/src/casting/index.ts
  • packages/squad-sdk/src/config/init.ts
  • packages/squad-sdk/src/config/team-capabilities.ts
  • packages/squad-sdk/src/presets/index.ts
  • packages/squad-sdk/src/presets/scaffold.ts
  • packages/squad-sdk/src/tools/index.ts
  • packages/squad-sdk/templates/casting-registry.json
squad-state (1 file)
  • .squad/casting/registry.json
templates (1 file)
  • .squad-templates/casting-registry.json
tests (23 files)
  • test/agent-provenance.test.ts
  • test/cast-parser.test.ts
  • test/casting-durable-registry.test.ts
  • test/casting-registry-template.test.ts
  • test/casting.test.ts
  • test/check-agent-binding.test.ts
  • test/cli/doctor.test.ts
  • test/cli/export-import.test.ts
  • test/cli/health-command.test.ts
  • test/cli/init-upgrade-parity.test.ts
  • test/cli/state-mcp.test.ts
  • test/cli/upgrade.test.ts
  • test/fixtures/agent-provenance/cases.json
  • test/gh-aw-activation-artifact-integrity.test.ts
  • test/gh-aw-bootstrap-workflow.test.ts
  • test/gh-aw-cast-validator.test.ts
  • test/gh-aw-quality.test.ts
  • test/init-scaffolding.test.ts
  • test/init-sdk.test.ts
  • test/presets.test.ts
  • test/state-backend.test.ts
  • test/team-capabilities-lifecycle.test.ts
  • test/template-sync.test.ts

⚠️ Critical Files

  • packages/squad-sdk/src/casting/index.ts
  • packages/squad-sdk/src/presets/index.ts
  • packages/squad-sdk/src/tools/index.ts

This report is generated automatically for every PR. See #733 for details.

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

🏗️ Architectural Review

⚠️ Architectural review: 2 warning(s).

Severity Category Finding Files
🟡 warning bootstrap-area 2 file(s) in the bootstrap area (packages/squad-cli/src/cli/core/) were modified. These files must maintain zero external dependencies. Review carefully. packages/squad-cli/src/cli/core/cast.ts, packages/squad-cli/src/cli/core/upgrade.ts
🟡 warning sweeping-refactor This PR touches 53 files (53 modified/added, 0 deleted). Large PRs are harder to review — consider splitting if possible. —

Automated architectural review — informational only.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The SDK provenance parser is currently more permissive than the documented/validated v1 contract (required fields and avatar path confinement), which can lead to consumers silently accepting malformed producer state.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

This PR introduces a versioned, producer-owned “agent identity provenance” contract in .squad/casting/registry.json, aiming to make agent IDs stable across renames/recasts, support retirement tombstones, and add optional avatar references while wiring validation through SDK/CLI and GH-AW workflows.

Changes:

  • Define and enforce squad-agent-provenance/v1 registry shape (schema/version, revision, timestamps, stable IDs, lifecycle/status, optional avatars).
  • Add SDK parsing/reconciliation APIs and wire them into CLI cast + SDK scaffold/presets.
  • Add fixtures/docs and expand tests + GH-AW validators to cover the new contract.
File Description
workflows/​squad.md Updates cast validator SHA and documents the new provenance registry semantics.
workflows/​squad-bootstrap.md Updates validator SHA and bootstrap contract text to reference v1 provenance requirements.
workflows/​shared/​squad-cast-validator.mjs Tightens registry validation to require v1 provenance fields and avatar path constraints.
test/​gh-aw-quality.test.ts Updates expected embedded validator SHA in the compiled workflow security contract test.
test/​gh-aw-cast-validator.test.ts Updates fixtures and expectations to match v1 provenance registry + SHA changes.
test/​gh-aw-bootstrap-workflow.test.ts Updates bootstrap workflow fixtures to emit v1 provenance registry shape.
test/​fixtures/​agent-provenance/​cases.json Adds fixture cases for valid/partial/unsupported provenance registries (including avatar).
test/​cast-parser.test.ts Adds coverage ensuring IDs are preserved across display-name changes and revision increments.
test/​agent-provenance.test.ts Adds SDK-level contract tests for parsing/reconciliation behavior and collision rules.
templates/​casting-registry.json Updates template registry to include v1 provenance root fields.
scripts/​validate-gh-aw-cast.mjs Mirrors GH-AW registry validation updates for local validation tooling.
packages/​squad-sdk/​templates/​casting-registry.json Updates SDK-shipped template registry to v1 provenance root fields.
packages/​squad-sdk/​src/​presets/​scaffold.ts Switches preset scaffolding to reconcile via provenance registry API (and fail on malformed JSON).
packages/​squad-sdk/​src/​casting/​index.ts Exposes provenance APIs/types from the SDK casting entrypoint.
packages/​squad-sdk/​src/​casting/​agent-provenance.ts Implements the v1 provenance parser/reconciler and associated types/errors.
packages/​squad-cli/​templates/​casting-registry.json Updates CLI template registry to include v1 provenance root fields.
packages/​squad-cli/​src/​cli/​core/​cast.ts Wires CLI casting to reconcile provenance registry, preserve stable IDs, and tombstone/move retired agents.
docs/​src/​content/​docs/​concepts/​agent-identity-provenance.md Adds consumer-facing contract documentation for agent identity provenance v1.
.squad-templates/​casting-registry.json Updates canonical Squad templates registry to include v1 provenance root fields.
.changeset/​agent-identity-provenance.md Adds changeset bumping SDK/CLI minor versions for the new provenance contract and APIs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +124 to +136
const displayName = typeof value.display_name === 'string'
? value.display_name.trim()
: typeof value.persistent_name === 'string'
? value.persistent_name.trim()
: '';
const persistentName = typeof value.persistent_name === 'string'
? value.persistent_name.trim()
: displayName;
const role = typeof value.role === 'string' ? value.role.trim() : '';
const universe = typeof value.universe === 'string' ? value.universe.trim() : '';
const status = value.status;
const createdAt = value.created_at;
const updatedAt = value.updated_at ?? value.created_at;
Comment on lines +73 to +74
Avatar references are optional and restricted to `.squad/agents/`. When the
field is absent, stale, inaccessible, or malformed, render no avatar. Do not
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Squad File Leakage Detected

The following .squad/ files were modified in this PR:

  • .squad/casting/registry.json

These files affect team routing, agent charters, and decisions.
If intentional, ensure approval from the team lead.

bradygaster and others added 3 commits September 21, 2026 15:43
Refs bradygaster/squadcaster#45

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes bradygaster/squadcaster#45

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Refs #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@bradygaster
bradygaster force-pushed the bradygaster-agent-identity-producer branch from 0098d10 to e9a2b17 Compare September 21, 2026 22:51
@bradygaster

Copy link
Copy Markdown
Collaborator Author

Revision ready for fresh independent rereview at e9a2b1798ef59459bac0defc6c9a91c0c449124c (supersedes rejected 0098d100).

The revision closes the three blockers: concurrency-safe atomic preset registry updates with conflict retry; complete fail-closed squad-work-agent-binding/v1 cross-row semantics; and versioned parseable roots in all four casting-registry templates.

Validation: 620 focused tests pass; SDK/CLI typecheck and builds pass; docs lint passes. Full suite: 9,161 passed with nine unrelated known worktree/external-state or compiled-baseline failures.

@copilot review

bradygaster and others added 2 commits September 21, 2026 15:55
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@bradygaster

Copy link
Copy Markdown
Collaborator Author

Exact-current-head rereview requested for frozen SHA 8805237bd467c3281d18b09eb0e0bde2ff8f686d.

This head adds commits 4b9e250 and 8805237 after the prior approval. The delta came from the separate SDK fixing provenance blockers session and intentionally extends atomicity to history/policy, locks the full preset scaffold transaction, updates init/upgrade registry fallbacks, expands tests, and restores the parser fail-closed guard.

Exact-head validation: SDK build and SDK/CLI typecheck pass; 689 focused tests pass; GitHub required full test and gh-aw strict compile checks pass. No further push or merge pending review.

@copilot review

bradygaster and others added 10 commits September 21, 2026 16:19
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The final tree retains the independently validated ABA-safe lock and roll-forward pair transaction implementation.

Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Harden legacy casting generation proof, validate pair commits before mutation, and report structured preset rollback uncertainty.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject outgoing history references to unknown registry agents before mutation and capture exact scaffold-written bytes for rollback comparison.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use the registry candidates' immutable normalized IDs in preset history snapshots and cover noncanonical agent basenames.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
bradygaster and others added 5 commits September 21, 2026 19:34
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Closes #2066

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@bradygaster
bradygaster merged commit a1a8e1f into dev Sep 22, 2026
19 checks passed
cherie-q added a commit to cherie-q/squad that referenced this pull request Oct 1, 2026
squad init and team casting failed on Windows with
"EPERM: operation not permitted, fsync" (regression from github#2066).

- flushDirectory() fsynced directory handles after each rename, which
  Windows rejects. Skip it on win32; the file-level fsync already ran.
- The lock publishes by renaming a candidate dir onto registry.lock.
  Windows reports a rename onto an existing directory as EPERM, not
  ENOTEMPTY/EEXIST, so a contended lock crashed instead of waiting.
  Treat win32 EPERM as contention in the sync and async acquirers, and
  name the last publish error in the timeout so a real permission
  problem isn't blamed on a phantom writer.
- Lock release retries the quarantine rename on transient win32
  EPERM/EACCES/EBUSY (antivirus holding a fresh owner.json) for up to
  1s, since a leftover registry.lock.recovery blocks every later
  writer. Deleting the already-quarantined copy is best-effort on win32.
- A blocked quarantine delete could leave registry.lock.released-*
  folders in .squad/casting/ with no later cleanup. Release now sweeps
  abandoned lock quarantines while holding the recovery guard; guard
  quarantines are swept only once older than the stale-lock age.

Tests: an emulated-Windows suite runs on any host, including the
ubuntu-only CI; each fix turns it red when reverted. The retry and
delete tests run for EPERM, EACCES and EBUSY. Child-process tests
import the module via a file:// URL so the existing durability suite
also runs on Windows.

Closes github#2106

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bradygaster added a commit that referenced this pull request Oct 2, 2026
squad init and team casting failed on Windows with
"EPERM: operation not permitted, fsync" (regression from #2066).

- flushDirectory() fsynced directory handles after each rename, which
  Windows rejects. Skip it on win32; the file-level fsync already ran.
- The lock publishes by renaming a candidate dir onto registry.lock.
  Windows reports a rename onto an existing directory as EPERM, not
  ENOTEMPTY/EEXIST, so a contended lock crashed instead of waiting.
  Treat win32 EPERM as contention in the sync and async acquirers, and
  name the last publish error in the timeout so a real permission
  problem isn't blamed on a phantom writer.
- Lock release retries the quarantine rename on transient win32
  EPERM/EACCES/EBUSY (antivirus holding a fresh owner.json) for up to
  1s, since a leftover registry.lock.recovery blocks every later
  writer. Deleting the already-quarantined copy is best-effort on win32.
- A blocked quarantine delete could leave registry.lock.released-*
  folders in .squad/casting/ with no later cleanup. Release now sweeps
  abandoned lock quarantines while holding the recovery guard; guard
  quarantines are swept only once older than the stale-lock age.

Tests: an emulated-Windows suite runs on any host, including the
ubuntu-only CI; each fix turns it red when reverted. The retry and
delete tests run for EPERM, EACCES and EBUSY. Child-process tests
import the module via a file:// URL so the existing durability suite
also runs on Windows.

Closes #2106

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Tamir Dresher <tamir.dresher@gmail.com>
Co-authored-by: Brady Gaster <41929050+bradygaster@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants