feat: add audit trail for detach operations (gt-h6eq.8)

Add DetachMoleculeWithAudit() function that logs detach operations
to .beads/audit.log in JSONL format. Each entry captures:
- timestamp
- operation type (detach, burn, squash)
- pinned_bead_id
- detached_molecule
- detached_by (agent identity)
- reason (optional)
- previous_state

Updated callers:
- runMoleculeDetach: logs "detach" operation
- runMoleculeBurn: logs "burn" operation with reason
- runMoleculeSquash: logs "squash" operation with digest ID

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-23 11:34:35 -08:00
parent d3657902a6
commit 9fa4a42030
3 changed files with 126 additions and 6 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/beads"
"github.com/steveyegge/gastown/internal/style"
"github.com/steveyegge/gastown/internal/workspace"
)
func runMoleculeAttach(cmd *cobra.Command, args []string) error {
@@ -59,8 +60,11 @@ func runMoleculeDetach(cmd *cobra.Command, args []string) error {
previousMolecule := attachment.AttachedMolecule
// Detach the molecule
_, err = b.DetachMolecule(pinnedBeadID)
// Detach the molecule with audit logging
_, err = b.DetachMoleculeWithAudit(pinnedBeadID, beads.DetachOptions{
Operation: "detach",
Agent: detectCurrentAgent(),
})
if err != nil {
return fmt.Errorf("detaching molecule: %w", err)
}
@@ -126,3 +130,20 @@ func runMoleculeAttachment(cmd *cobra.Command, args []string) error {
return nil
}
// detectCurrentAgent returns the current agent identity based on working directory.
// Returns empty string if identity cannot be determined.
func detectCurrentAgent() string {
cwd, err := os.Getwd()
if err != nil {
return ""
}
townRoot, err := workspace.FindFromCwd()
if err != nil || townRoot == "" {
return ""
}
ctx := detectRole(cwd, townRoot)
return buildAgentIdentity(ctx)
}