brainiac-basecamp 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c8050e48cf49fc743e8e1cf01db98abcb279fa7b8a2c70b99ee77cf2f331378
4
- data.tar.gz: 0eb5638888a2369c61b1b0cc3bfed7c4729df1dc1ed2e14e56af69ca36280644
3
+ metadata.gz: 9baa0382677cf44d0ef67156c66420348c00b74e7532f6b410dab9d8e61f7e90
4
+ data.tar.gz: 353777dfdc0f84ba57e89b8e36249867e9fec29f46ebfe4af0ac090704e14dff
5
5
  SHA512:
6
- metadata.gz: 8aca50da9477027ff6800582dea934506a76897256eb4c91d8f2a9cfd8f27b3c786784a98410f487eb9c77d83924a74ee9ea9e753fe8d21c2f57c885afd7de30
7
- data.tar.gz: c64f4de4ff526fa7c0a18149309b61a917b04f373ea02bc31855b752b9ce0ad820df9b040b90fe71d4fdcd2d5f7221e2ef5d3f297b6a90747cbe738b632f667f
6
+ metadata.gz: 8f2eee7436544bcfc8278bbb22add64237c6dc4bf4256930566741ce60f683364ec24e9d2784d6765ca418bada76e6f5be8cbbc625b2384f64d1b4d5b1f6d65b
7
+ data.tar.gz: a72b44713badc00c8f3bbfc4c433afbf832550e11675d9bb8e384131209c4f1a1d1d810be885fe620bf68762cf1632cf855c209c617ad3b5a57df044895f6150
@@ -790,12 +790,12 @@ module Brainiac
790
790
  return unless project_config && project_config["repo_path"]
791
791
 
792
792
  agent_name = Orchestrator.send(:resolve_agent_for_project, project_key) || epic["agent"]
793
- prompt = <<~PROMPT
794
- ## Changes Requested Fizzy Card ##{card_number}
795
-
796
- Review feedback needs attention on PR ##{task['pr_number']}. Read the review,
797
- make the requested fixes, commit and push them, then update the Fizzy card.
798
- PROMPT
793
+ # Only build a "changes requested" prompt when there is a real PR to
794
+ # act on. A stale in_flight card recovered by the orchestrator has no
795
+ # PR number yet — handing an agent "...fixes on PR #" with a blank
796
+ # number is nonsense and the session dies asking for clarification.
797
+ # In that case dispatch a clean "start implementation" prompt instead.
798
+ prompt = build_impl_prompt(card_number: card_number, pr_number: task["pr_number"])
799
799
  github_repo = project_config["github_repo"]
800
800
  agent_env = github_repo ? ReviewGate.send(:resolve_agent_github_env, agent_name, github_repo) : {}
801
801
  pid, log_file = method(:run_agent).call(
@@ -824,6 +824,36 @@ module Brainiac
824
824
  LOG.error "[Basecamp:Hooks] Direct implementation dispatch failed: #{e.message}" if defined?(LOG)
825
825
  end
826
826
 
827
+ # Build the implementation prompt for a direct dispatch.
828
+ #
829
+ # When +pr_number+ is present the card already has an open PR, so the
830
+ # agent is asked to address review feedback. When it is absent (a stale
831
+ # in_flight card the orchestrator recovered, or a first dispatch) the
832
+ # agent is asked to start the implementation from scratch — never with a
833
+ # blank "PR #" that a real PR would have filled in.
834
+ #
835
+ # @param card_number [Integer, String] Fizzy card number
836
+ # @param pr_number [Integer, String, nil] PR number, if one exists
837
+ # @return [String] the prompt text
838
+ def build_impl_prompt(card_number:, pr_number:)
839
+ if pr_number.to_s.strip.empty?
840
+ <<~PROMPT
841
+ ## Implement — Fizzy Card ##{card_number}
842
+
843
+ Pick up Fizzy card ##{card_number} and implement it. Read the card for
844
+ requirements, do the work in a branch, commit and push, open a PR, then
845
+ update the Fizzy card. There is no existing PR for this card yet.
846
+ PROMPT
847
+ else
848
+ <<~PROMPT
849
+ ## Changes Requested — Fizzy Card ##{card_number}
850
+
851
+ Review feedback needs attention on PR ##{pr_number}. Read the review,
852
+ make the requested fixes, commit and push them, then update the Fizzy card.
853
+ PROMPT
854
+ end
855
+ end
856
+
827
857
  # Find a PR number by branch name pattern.
828
858
  def find_pr_number(repo_path:, branch:)
829
859
  # Try exact match first
@@ -593,6 +593,25 @@ module Brainiac
593
593
  nil
594
594
  end
595
595
 
596
+ # Whether a card's completion is backed by real evidence of shipped work.
597
+ #
598
+ # A card genuinely completes when it has an associated PR that merged (or,
599
+ # at minimum, a tracked PR number). Without any PR evidence the completion
600
+ # is almost certainly spurious — a stale ledger flag left behind by a
601
+ # basecamp re-sync that dropped merged cards — and we should not treat it
602
+ # as a real completion that warrants an epic-review checkpoint.
603
+ #
604
+ # @param epic [Hash] epic state
605
+ # @param card_number [Integer, String] the card claimed complete
606
+ # @return [Boolean]
607
+ def card_completion_verified?(epic, card_number)
608
+ task = epic["tasks"].find { |t| t["fizzy_card"] == card_number.to_i }
609
+ return false unless task
610
+
611
+ # A tracked PR number is our recorded evidence that work shipped.
612
+ !task["pr_number"].to_s.strip.empty?
613
+ end
614
+
596
615
  # Dispatch an agent to review the epic state after a task completes.
597
616
  # This ensures the remaining plan still makes sense given implementation decisions.
598
617
  # The callback is called after the review completes.
@@ -606,6 +625,22 @@ module Brainiac
606
625
  return
607
626
  end
608
627
 
628
+ # Only post a "just completed" checkpoint when the card actually shipped
629
+ # work. A ledger flagged `complete` with no PR (and no merge) means the
630
+ # completion was spurious — usually the basecamp re-sync dropping merged
631
+ # cards and leaving a stale flag. Posting "Card #N just completed" in that
632
+ # case is a false claim that spawns a pointless epic-review reflex.
633
+ # Still run the callback so the resolver can advance (it correctly does
634
+ # nothing for cards that remain blocked).
635
+ unless card_completion_verified?(epic, completed_card_number)
636
+ if defined?(LOG)
637
+ LOG.warn "[Basecamp:Orchestrator] Skipping epic review after card " \
638
+ "##{completed_card_number} — no PR/merge evidence of completion"
639
+ end
640
+ callback&.call
641
+ return
642
+ end
643
+
609
644
  LOG.info "[Basecamp:Orchestrator] Dispatching epic review after card ##{completed_card_number}" if defined?(LOG)
610
645
 
611
646
  # Ensure epic memory exists (in case this epic started before the feature)
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Basecamp
6
- VERSION = "0.0.24"
6
+ VERSION = "0.0.25"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac-basecamp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.24
4
+ version: 0.0.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis