feat(audit): add append-only agent audit trail (.beads/interactions.jsonl)
Implements audit logging for agent interactions to support auditing and dataset generation (fixes #649). New features: - .beads/interactions.jsonl (append-only audit log) - bd audit record: log LLM calls, tool calls, or pipe JSON via stdin - bd audit label <id>: append labels (good/bad) for dataset curation - bd compact --audit: optionally log LLM prompt/response during compaction - bd init: creates empty interactions.jsonl - bd sync: includes interactions.jsonl in staging Audit entries are append-only - labeling creates new entries that reference parent entries by ID. Closes #649 Co-authored-by: Dmitry Chichkov <dchichkov@nvidia.com> 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -195,6 +195,16 @@ With --stealth: configures global git settings for invisible beads usage:
|
||||
}
|
||||
}
|
||||
|
||||
// Create empty interactions.jsonl file (append-only agent audit log)
|
||||
interactionsPath := filepath.Join(beadsDir, "interactions.jsonl")
|
||||
if _, err := os.Stat(interactionsPath); os.IsNotExist(err) {
|
||||
// nolint:gosec // G306: JSONL file needs to be readable by other tools
|
||||
if err := os.WriteFile(interactionsPath, []byte{}, 0644); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: failed to create interactions.jsonl: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Create metadata.json for --no-db mode
|
||||
cfg := configfile.DefaultConfig()
|
||||
if err := cfg.Save(beadsDir); err != nil {
|
||||
@@ -234,6 +244,16 @@ With --stealth: configures global git settings for invisible beads usage:
|
||||
fmt.Fprintf(os.Stderr, "Warning: failed to create/update .gitignore: %v\n", err)
|
||||
// Non-fatal - continue anyway
|
||||
}
|
||||
|
||||
// Ensure interactions.jsonl exists (append-only agent audit log)
|
||||
interactionsPath := filepath.Join(beadsDir, "interactions.jsonl")
|
||||
if _, err := os.Stat(interactionsPath); os.IsNotExist(err) {
|
||||
// nolint:gosec // G306: JSONL file needs to be readable by other tools
|
||||
if err := os.WriteFile(interactionsPath, []byte{}, 0644); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Warning: failed to create interactions.jsonl: %v\n", err)
|
||||
// Non-fatal - continue anyway
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure parent directory exists for the database
|
||||
@@ -1555,7 +1575,6 @@ Aborting.`, yellow("⚠"), dbPath, cyan("bd list"), prefix)
|
||||
return nil // No database found, safe to init
|
||||
}
|
||||
|
||||
|
||||
// landingThePlaneSection is the "landing the plane" instructions for AI agents
|
||||
// This gets appended to AGENTS.md and @AGENTS.md during bd init
|
||||
const landingThePlaneSection = `
|
||||
@@ -1608,17 +1627,17 @@ func updateAgentFile(filename string, verbose bool) error {
|
||||
// File doesn't exist - create it with basic structure
|
||||
newContent := fmt.Sprintf(`# Agent Instructions
|
||||
|
||||
This project uses **bd** (beads) for issue tracking. Run ` + "`bd onboard`" + ` to get started.
|
||||
This project uses **bd** (beads) for issue tracking. Run `+"`bd onboard`"+` to get started.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
` + "```bash" + `
|
||||
`+"```bash"+`
|
||||
bd ready # Find available work
|
||||
bd show <id> # View issue details
|
||||
bd update <id> --status in_progress # Claim work
|
||||
bd close <id> # Complete work
|
||||
bd sync # Sync with git
|
||||
` + "```" + `
|
||||
`+"```"+`
|
||||
%s
|
||||
`, landingThePlaneSection)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user