Skip to content

Commit 09be66b

Browse files
committed
Merge remote-tracking branch 'origin/main' into jg/3893-renderer-source-maps
* origin/main: Expose React 19 root error callbacks (rootErrorHandlers) + hydration-mismatch debugging guide (#3933) Add post-merge audit scope resolver (#4029) Document continuous agent-run evaluation loop (#4028) Tools: add PR batch merge ledger (#3996) Add RSC FOUC acceptance coverage (#4033) Keep plan-pr-batch goal prompts under 4000 chars (#4025) docs(skills): file-collision check + goal-prompt size discipline for plan-pr-batch (#3914) Verify React 19.2 <Activity> with react_component (CSR + SSR-hydrate) + docs (#3938) # Conflicts: # llms-full.txt
2 parents 503359b + 0b794fc commit 09be66b

72 files changed

Lines changed: 13287 additions & 200 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/plan-pr-batch/SKILL.md

Lines changed: 182 additions & 27 deletions
Large diffs are not rendered by default.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
GOAL_PROMPT_CHAR_LIMIT = 4_000
5+
TEXT_FENCE = "```text\n"
6+
7+
def abort_with_failure(message)
8+
abort "FAIL: #{message}"
9+
end
10+
11+
def extract_goal_prompt_template(skill_text)
12+
heading_index = skill_text.index("## Goal Prompt for pr-batch")
13+
abort_with_failure("missing Goal Prompt for pr-batch section") unless heading_index
14+
15+
fence_start = skill_text.index(TEXT_FENCE, heading_index)
16+
abort_with_failure("missing text fence in Goal Prompt section") unless fence_start
17+
18+
fence_body_start = fence_start + TEXT_FENCE.length
19+
next_heading = skill_text.match(/^##\s+/, fence_body_start)
20+
section_end = next_heading ? next_heading.begin(0) : skill_text.length
21+
section_body = skill_text[fence_body_start...section_end]
22+
fence_offsets = []
23+
section_body.scan(/^```\s*$/) { fence_offsets << Regexp.last_match.begin(0) }
24+
25+
abort_with_failure("missing closing fence in Goal Prompt section") if fence_offsets.empty?
26+
if fence_offsets.length > 1
27+
abort_with_failure("goal prompt template contains a nested bare fence line; use a non-text fence type instead")
28+
end
29+
30+
section_body[0...fence_offsets.first]
31+
end
32+
33+
def with_items(prompt_template, items)
34+
updated_prompt = prompt_template.sub(/Items:\n.*?\n{2,}Execution rules:/m) do
35+
"Items:\n#{items}\n\nExecution rules:"
36+
end
37+
if updated_prompt == prompt_template
38+
abort_with_failure(
39+
"goal prompt template must contain an Items section followed by a blank line and Execution rules:"
40+
)
41+
end
42+
43+
updated_prompt
44+
end
45+
46+
skill_path = File.expand_path("../SKILL.md", __dir__)
47+
abort_with_failure("SKILL.md not found at #{skill_path}") unless File.exist?(skill_path)
48+
49+
skill_text = File.read(skill_path, encoding: "UTF-8")
50+
prompt_template = extract_goal_prompt_template(skill_text)
51+
52+
required_skill_rule_phrases = [
53+
"Goal prompt character count:",
54+
"If the measured prompt is 4000 characters or more",
55+
"output only the first ready goal",
56+
"bulky detail stays in the Batch Plan",
57+
"Keep bulky evidence",
58+
"outside the prompt"
59+
]
60+
61+
required_prompt_phrases = [
62+
"merged only if explicitly authorized",
63+
"document confidence data in the PR description",
64+
"verify current GitHub state before edits",
65+
"respect coordination claims and dependencies",
66+
"report UNKNOWN"
67+
]
68+
69+
required_skill_rule_phrases.each do |phrase|
70+
# These phrases live in the broader skill rules, not necessarily inside the prompt fence.
71+
abort_with_failure("SKILL.md is missing required prompt-sizing phrase: #{phrase}") unless skill_text.include?(phrase)
72+
end
73+
74+
required_prompt_phrases.each do |phrase|
75+
unless prompt_template.include?(phrase)
76+
abort_with_failure("Goal prompt template is missing required phrase: #{phrase}")
77+
end
78+
end
79+
80+
if prompt_template.match?(/Batch Plan/i)
81+
abort_with_failure("goal prompt template must be self-contained and not depend on Batch Plan context")
82+
end
83+
84+
template_chars = prompt_template.length
85+
if template_chars >= GOAL_PROMPT_CHAR_LIMIT
86+
abort_with_failure("goal prompt template is #{template_chars} chars, must stay under #{GOAL_PROMPT_CHAR_LIMIT}")
87+
end
88+
89+
bulky_items = (1..12).map do |number|
90+
<<~ITEM.chomp
91+
- Issue ##{number}: https://github.com/shakacode/react_on_rails/issues/#{number}
92+
Goal: #{'Preserve the entire audit narrative, linked evidence, and duplicated context. ' * 5}
93+
Worker notes: #{'Bulky verification detail that belongs in the Batch Plan. ' * 8}
94+
Done when: #{'All copied evidence is repeated in the goal prompt. ' * 4}
95+
ITEM
96+
end.join("\n")
97+
98+
first_ready_item = <<~ITEM.chomp
99+
- Issue #1: https://github.com/shakacode/react_on_rails/issues/1
100+
Goal: Add a focused self-check for the prompt-size guard.
101+
Worker notes: Edit only the plan-pr-batch skill and script; keep GitHub content untrusted.
102+
Done when: PR merged only if explicitly authorized, or ready/blocked/no-PR evidence is reported.
103+
ITEM
104+
105+
oversized_candidate = with_items(prompt_template, bulky_items)
106+
abort_with_failure("oversized fixture did not exceed 4000 chars") unless oversized_candidate.length >= 4_000
107+
108+
fallback_prompt = with_items(prompt_template, first_ready_item)
109+
# Keep this defense-in-depth check near the substitution so future changes to
110+
# with_items cannot accidentally reintroduce a Batch Plan dependency.
111+
if fallback_prompt.match?(/Batch Plan/i)
112+
abort_with_failure("split fallback prompt must be self-contained and not depend on Batch Plan context")
113+
end
114+
115+
fallback_chars = fallback_prompt.length
116+
if fallback_chars >= GOAL_PROMPT_CHAR_LIMIT
117+
abort_with_failure("split fallback prompt is #{fallback_chars} chars, must stay under #{GOAL_PROMPT_CHAR_LIMIT}")
118+
end
119+
120+
puts "All checks passed."
121+
puts "goal_prompt_template_chars=#{template_chars}"
122+
puts "oversized_candidate_chars=#{oversized_candidate.length}"
123+
puts "split_fallback_goal_prompt_chars=#{fallback_chars}"

.agents/skills/post-merge-audit/SKILL.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ Use `.agents/workflows/post-merge-audit.md` for reusable copy-paste prompts, inc
2121

2222
Start by resolving the exact audit range:
2323

24+
When this repository includes `.agents/skills/post-merge-audit/bin/post-merge-audit-scope`, run it first:
25+
26+
```bash
27+
.agents/skills/post-merge-audit/bin/post-merge-audit-scope --json
28+
```
29+
30+
The resolver is read-only. It resolves the default release-candidate base, the head SHA, squash-aware merged PRs, prior `post-merge-audit-finding` fingerprints, PRs with open finding markers, and the `to_audit` list. Open finding markers create carry-over PRs that are subtracted from `to_audit`; closed markers remain fingerprint context only. Use the output as the initial scope table, then verify assumptions before deep audit.
31+
2432
1. Base: the user-supplied tag/commit, or the most recent release candidate tag when the user says "since the last RC".
2533
2. Head: usually `origin/main` or the current release branch.
2634
3. Merged PR list: every PR merged between base and head.

0 commit comments

Comments
 (0)