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
2 changes: 1 addition & 1 deletion desktop/src-tauri/src/managed_agents/nest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const BUZZ_CLI_SKILL_MD: &str = include_str!("nest_skill.md");
/// Template content version for AGENTS.md static content (above managed markers).
/// Bump this when changing `nest_agents.md` to trigger refresh on existing installs.
/// Version 1 is implicitly "before this mechanism existed" (no version file).
const NEST_AGENTS_VERSION: u32 = 4;
const NEST_AGENTS_VERSION: u32 = 5;

/// Template content version for SKILL.md.
/// Bump this when changing `nest_skill.md` to trigger refresh on existing installs.
Expand Down
43 changes: 43 additions & 0 deletions desktop/src-tauri/src/managed_agents/nest/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ fn nest_skill_contains_safe_mention_workflow() {
assert!(BUZZ_CLI_SKILL_MD.contains("never changes membership automatically"));
}

#[test]
fn nest_agents_template_separates_commit_attribution_claims() {
assert_eq!(AGENTS_MD.matches("## Git Commit Attribution").count(), 1);
assert!(AGENTS_MD.contains(
"Git authorship, co-authorship, DCO sign-off, and cryptographic signing are separate claims"
));
assert!(AGENTS_MD
.contains("Request, approval, review, or accountability alone is not co-authorship"));
assert!(AGENTS_MD.contains("A sign-off is not an approval marker"));
assert!(AGENTS_MD.contains("Never use another person's signing key"));
assert!(AGENTS_MD.contains("inspect every outgoing commit against the actual upstream or base"));
assert!(AGENTS_MD.contains("An agent-owned repository may use the agent as author"));
assert!(!AGENTS_MD.contains("every commit MUST include a `Signed-off-by`"));
}

#[test]
fn ensure_nest_creates_all_dirs_and_agents_md() {
let tmp = tempfile::tempdir().unwrap();
Expand Down Expand Up @@ -431,6 +446,34 @@ fn refresh_agents_md_writes_version_file() {
assert_eq!(version.trim(), NEST_AGENTS_VERSION.to_string());
}

#[test]
fn refresh_agents_md_upgrades_attribution_and_preserves_owned_content() {
let tmp = tempfile::tempdir().unwrap();
let root = tmp.path().join(".buzz");
ensure_nest_at(&root).unwrap();

let agents_md = root.join("AGENTS.md");
fs::write(
&agents_md,
"# Buzz Nest\n\n## Git Commit Identity\n\n\
- **Human sign-off (required):** every commit MUST include a `Signed-off-by`.\n\n\
<!-- BEGIN BUZZ MANAGED — regenerated automatically, do not edit below -->\n\
## Active Agents\n\n| Name | Persona | How to address |\n\
|------|---------|----------------|\n| Kit | Builder | @Kit |\n\
<!-- END BUZZ MANAGED -->\n\n## Local Notes\n\nKeep me.\n",
)
.unwrap();
fs::write(root.join(".nest-agents-version"), "4\n").unwrap();

ensure_nest_at(&root).unwrap();

let content = fs::read_to_string(&agents_md).unwrap();
assert_eq!(content.matches("## Git Commit Attribution").count(), 1);
assert!(!content.contains("**Human sign-off (required):**"));
assert!(content.contains("| Kit | Builder | @Kit |"));
assert!(content.contains("## Local Notes\n\nKeep me."));
}

#[test]
fn refresh_skill_md_writes_version_file() {
let tmp = tempfile::tempdir().unwrap();
Expand Down
17 changes: 10 additions & 7 deletions desktop/src-tauri/src/managed_agents/nest_agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,18 @@ created: 2026-01-15
- **`.scratch/` is disposable** — don't rely on it across sessions
- **Stay on task** — only stage files relevant to your current work

## Git Commit Identity
## Git Commit Attribution

The human operator signs off for accountability.
Git authorship, co-authorship, DCO sign-off, and cryptographic signing are separate claims. Follow repository-local rules and the authorizing human's explicit directions; do not infer attribution from repository ownership or from who requested, approved, or reviewed the work.

- **Human sign-off (required):** every commit MUST include a `Signed-off-by` trailer for the human operator who is responsible for the agent's work. Add via `git commit --trailer "Signed-off-by: Human Name <human@email>"`. One blank line must separate trailers from the commit body.
- **Human credit (`Co-authored-by`):** every commit MUST also include a `Co-authored-by` trailer for the same human operator, with identical name and email to the `Signed-off-by` line. GitHub parses `Co-authored-by` for contribution-graph credit; `Signed-off-by` alone does not grant it. Add via `git commit --trailer "Co-authored-by: Human Name <human@email>"`. Place `Co-authored-by` before `Signed-off-by` in the trailer block.
- **Discovering the human's identity:** read `git config user.name` and `git config user.email` from the working repository. These reflect the human operator's configured identity for that repo (which may differ from their global config). Use these exact values for both trailers. Do NOT hardcode, guess, or prompt for the email — the repo config is the source of truth. If `git config user.email` returns empty, STOP and ask the human operator for their name and email before committing.
- **Signing:** if the agent has a registered signing key, sign commits. If not, commits will land unverified — this is acceptable until agent SSH keys are provisioned. Do NOT use the human's signing key.
- **Verify before pushing:** `git log -1` should show the human's `Signed-off-by` trailer.
- **Author:** use the person or agent required by the applicable policy. If no policy specifies an author, use the identity that actually authored the change.
- **Co-authors:** add `Co-authored-by` only for other people or agents who materially authored the change. Request, approval, review, or accountability alone is not co-authorship.
- **DCO:** add `Signed-off-by` only when repository policy requires that identity's DCO certification. A sign-off is not an approval marker.
- **Identity:** resolve required identities from trusted local configuration or explicit verified direction; never hard-code or guess them. A managed runtime may make effective `git config user.*` values identify the agent. Stop and ask if a required identity cannot be established.
- **Signing:** use only the signing key configured for the committing identity. Never use another person's signing key.
- **Verify before pushing:** inspect every outgoing commit against the actual upstream or base and confirm its attribution matches the applicable policy.

A repository may require an accountable human as author and the implementing agent as co-author. An agent-owned repository may use the agent as author and require no human trailer. In both cases, repository-local policy controls.

<!-- BEGIN BUZZ MANAGED — regenerated automatically, do not edit below -->
## Active Agents
Expand Down
Loading