@agent-native/core 0.222.0-nightly-20261029032851 β 0.222.0
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.
- package/dist/agent/production-agent.js +7 -2
- package/dist/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +6 -1
- package/dist/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +287 -0
- package/dist/templates/factory/.agents/skills/review-prs/SKILL.md +23 -0
- package/package.json +4 -4
- package/src/templates/factory/.agents/skills/review-latest-feedback/SKILL.md +6 -1
- package/src/templates/factory/.agents/skills/review-latest-feedback/references/slack-reaction-replies.md +287 -0
- package/src/templates/factory/.agents/skills/review-prs/SKILL.md +23 -0
|
@@ -9382,6 +9382,8 @@ export async function chainServerDrivenContinuation(opts) {
|
|
|
9382
9382
|
// Approval selectors apply only to the request that consumes their one-shot grants.
|
|
9383
9383
|
delete continuationBody.approvedToolCalls;
|
|
9384
9384
|
delete continuationBody.approvedToolCallAskIds;
|
|
9385
|
+
// The initial admission consumed this one-time queued-message claim.
|
|
9386
|
+
delete continuationBody.queuedMessageClaimId;
|
|
9385
9387
|
delete continuationBody[AGENT_CHAT_BACKGROUND_RUN_FIELD];
|
|
9386
9388
|
const markRunsAbortedOrThrow = async (...runIds) => {
|
|
9387
9389
|
const results = await Promise.allSettled(runIds.map(async (targetRunId) => {
|
|
@@ -11536,12 +11538,15 @@ export function createProductionAgentHandler(options) {
|
|
|
11536
11538
|
let durableDispatchPayload;
|
|
11537
11539
|
if (dispatchToBackground) {
|
|
11538
11540
|
try {
|
|
11539
|
-
|
|
11541
|
+
const dispatchBody = {
|
|
11540
11542
|
...body,
|
|
11541
11543
|
...(Array.isArray(attachments) || requestAttachments.length > 0
|
|
11542
11544
|
? { attachments: requestAttachments }
|
|
11543
11545
|
: {}),
|
|
11544
|
-
}
|
|
11546
|
+
};
|
|
11547
|
+
// This one-time claim authorizes only the request that consumes it.
|
|
11548
|
+
delete dispatchBody.queuedMessageClaimId;
|
|
11549
|
+
durableDispatchPayload = serializeDurableDispatchPayload(dispatchBody);
|
|
11545
11550
|
}
|
|
11546
11551
|
catch (error) {
|
|
11547
11552
|
if (!(error instanceof DurableAttachmentReferenceRequiredError)) {
|
|
@@ -21,6 +21,10 @@ not judged by ledgers, receipts, or checker output, so don't produce them.
|
|
|
21
21
|
|
|
22
22
|
## The contract
|
|
23
23
|
|
|
24
|
+
The detailed Slack reaction and reply rules are in
|
|
25
|
+
[slack-reaction-replies.md](references/slack-reaction-replies.md); read it before
|
|
26
|
+
marking, replying to, or closing any Slack report.
|
|
27
|
+
|
|
24
28
|
Slack reactions on a report's root message mean exactly this:
|
|
25
29
|
|
|
26
30
|
| Mark | Meaning | When to add |
|
|
@@ -43,7 +47,8 @@ might need to take back. Every π you add ends the run with a reply, plus
|
|
|
43
47
|
either β
or π«, or a fix PR that is still open and lists the report (its
|
|
44
48
|
merge adds the β
). A π with no follow-up is the most common complaint about this workflow.
|
|
45
49
|
|
|
46
|
-
Every claimed report gets **one** reply in its thread per outcome.
|
|
50
|
+
Every claimed report gets **one** reply in its thread per outcome. The one exception is
|
|
51
|
+
the merged `β
` close-out after an in-review reply, which gets no second reply. People
|
|
47
52
|
have pushed back on replies that were long, technical, condescending, vague
|
|
48
53
|
about who does what next, or that handed them work. Each reply must be:
|
|
49
54
|
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Slack Reaction Replies
|
|
2
|
+
|
|
3
|
+
Use the connected Slack integration for every Slack read and write. Never use a browser, screenshots, or UI automation to operate Slack.
|
|
4
|
+
|
|
5
|
+
At sweep exit, reconcile every report root in the scoped inventory that has
|
|
6
|
+
this task's `π`, `β
`, or `π«`, including marks left by earlier runs. Capture
|
|
7
|
+
the exact Slack actor ID used by the connected tool at sweep start. A mark is
|
|
8
|
+
owned by this task only when its reaction owner ID matches that actor ID and the
|
|
9
|
+
root is the workflow's by the parent skill's evidence: a bot-disclosure reply from
|
|
10
|
+
that account, or a root listed under "Claimed, not yet answered" in memory.md. A
|
|
11
|
+
matching reaction without that evidence is a manual mark: leave it alone. Keep
|
|
12
|
+
the disposition, evidence, scopes, and human actions in the internal inventory.
|
|
13
|
+
Post a reporter reply when this run adds a root reaction, when a newer human reporter
|
|
14
|
+
message needs a direct answer, or when this workflow owns a root from an earlier run
|
|
15
|
+
that has no verified reply in its thread yet, unless a person is already handling the root
|
|
16
|
+
or has asked the workflow to stop. The reply is one short, plain-language
|
|
17
|
+
sentence (about 25 words at most), plus the exact bot disclosure, which does not count toward
|
|
18
|
+
that limit. If the root asks a question, that sentence answers
|
|
19
|
+
it first and also explains only the reaction(s) added in this run. An answer to a newer human message
|
|
20
|
+
answers only that message. Skip the reply when the only reaction added is the merged
|
|
21
|
+
`β
` close-out after an earlier "in review" reply; that close-out gets no second
|
|
22
|
+
reply. Do not send progress, merge, or deployment updates. Never explain absent or
|
|
23
|
+
unchanged reactions or whether a tracker ticket exists. If reporter input is
|
|
24
|
+
needed, add `π«` and ask one direct question in that reply. Read back each new
|
|
25
|
+
reaction and reply.
|
|
26
|
+
|
|
27
|
+
Keep prior replies as history. Do not edit or add a status reply merely to
|
|
28
|
+
describe changed evidence, an existing reaction, or completed follow-up work.
|
|
29
|
+
When a new reaction is added, use one short sentence plus the exact bot
|
|
30
|
+
disclosure.
|
|
31
|
+
|
|
32
|
+
When editing an ordinary Slack reply, pass its visible body as
|
|
33
|
+
`message.markdown_text` to `slack_edit_message`; `message.text` is a fallback
|
|
34
|
+
for structured block messages and may leave the visible reply unchanged. Treat
|
|
35
|
+
the returned message ID as acknowledgment only. Read the exact reply back with
|
|
36
|
+
`slack_read_thread` and compare the stored body to the intended status before
|
|
37
|
+
counting it as posted. Use `slack_send_message` only when a new reply is
|
|
38
|
+
needed, with its `message` field and the root `thread_ts`.
|
|
39
|
+
|
|
40
|
+
`slack_read_thread` may append a synthetic `Status marks:` summary after the
|
|
41
|
+
thread. That is connector metadata, not part of any Slack message; do not copy
|
|
42
|
+
it into a reply. Likewise, omit connector-added `Sent using ChatGPT` footer
|
|
43
|
+
text from the intended body. `slack_send_message` may append that footer to a
|
|
44
|
+
new reply; if it does, remove it by editing with `message.markdown_text`, then
|
|
45
|
+
read the reply back again. Include the exact bot disclosure in the visible body
|
|
46
|
+
yourself; the connector footer is not a substitute.
|
|
47
|
+
|
|
48
|
+
Apply reactions to the report root, not the status reply: call
|
|
49
|
+
`slack_add_reaction` with the root's `channel_id`, its timestamp as
|
|
50
|
+
`message_ts`, and the emoji name without colons (`eyes`, `white_check_mark`, or
|
|
51
|
+
`ticket`). A colon-coded emoji mentioned in reply text does not add a reaction.
|
|
52
|
+
After each reaction call, read the root with `slack_get_reactions` and verify
|
|
53
|
+
the intended emoji and this actor's ID are present before recording it or
|
|
54
|
+
moving to another report. A successful tool response is only an acknowledgment;
|
|
55
|
+
the readback is the proof. If a reaction cannot be reconciled, record the exact
|
|
56
|
+
blocker instead of treating the reply text as a substitute.
|
|
57
|
+
|
|
58
|
+
Channel reads may expose a thread reply as a separate row. Resolve its
|
|
59
|
+
`thread_ts` or permalink and inventory it as a reply to the root, not as a new
|
|
60
|
+
report. Put new reactions for an ordinary report on its root; do not add another
|
|
61
|
+
`π` to a reply just because it appears as a channel row. Preserve any legacy
|
|
62
|
+
reaction already on a reply, read it back, and reconcile the actual root
|
|
63
|
+
separately. A reply that raises a genuinely distinct issue stays in the source
|
|
64
|
+
manifest as a reply row, but scope, disposition, handoff, and checkoff evidence
|
|
65
|
+
belong to the actual root row. Record the distinct issue as a separate scope on
|
|
66
|
+
that root and verify it independently. Do not invent a second root or put a
|
|
67
|
+
root checkoff on the reply. Record both the source message timestamp and root
|
|
68
|
+
thread timestamp; if the connector hides `thread_ts`, resolve the permalink
|
|
69
|
+
before recording it.
|
|
70
|
+
|
|
71
|
+
The parent inventory must retain the reaction-owner IDs and the same-parent
|
|
72
|
+
reply timestamp, author ID, disposition, evidence, and read-back text for every
|
|
73
|
+
root this actor marks with `π`, `β
`, or `π«`. Record an explicit decision for
|
|
74
|
+
both `β
` and `π«` on every such root: `present` with its scope, or `none` with
|
|
75
|
+
the reason no mark applies. Record verified fixed scopes with their proof and
|
|
76
|
+
each distinct human handoff with its scope, owner, and action. Before the recap, reconcile every owned root in the inventory by hand. Incomplete
|
|
77
|
+
source coverage or owned-root reconciliation means the sweep is not done. For
|
|
78
|
+
explicitly narrowed scope, keep the active user request as a separate record in
|
|
79
|
+
the inventory. This step does not authorize
|
|
80
|
+
changing another actor's reactions or replies.
|
|
81
|
+
|
|
82
|
+
## Prior questions and reporter replies
|
|
83
|
+
|
|
84
|
+
At sweep start, search the exact bot disclosure in each scoped channel and
|
|
85
|
+
exhaust the pages to find prior questions and their context:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
slack_search: "this was sent from a bot." in:<#CHANNEL>
|
|
89
|
+
sort=timestamp sort_dir=asc include_context=true max_context_length=300
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Also scan channel messages from the saved reply cursor; on the first run, scan
|
|
93
|
+
available history. Since `after:` is date-only, start one day before the cursor,
|
|
94
|
+
exhaust pages, resolve hits to their root, and advance the cursor only through
|
|
95
|
+
processed messages. Read inherited threads carrying any of this actor's root marks (`π`, `β
`,
|
|
96
|
+
or `π«`): a checkmark closes only its verified scope, not a newer reporter
|
|
97
|
+
answer or another open scope. Do not reply or react on another actor's root
|
|
98
|
+
when work is handed off for investigation; that handoff permits local
|
|
99
|
+
investigation only. A separate explicit authorization is required to post a
|
|
100
|
+
reporter-facing reply or change that actor's reactions.
|
|
101
|
+
|
|
102
|
+
Count an answer only when a human posts after the question, without this
|
|
103
|
+
workflow's disclosure, and the reply addresses it. Read the full thread to
|
|
104
|
+
exclude partial, unrelated, or deferred answers; a newer human post reopens the
|
|
105
|
+
question. Attempt the fix with new evidence before asking again. Do not send a
|
|
106
|
+
progress reply when no reaction is added. Do not ask again while the question
|
|
107
|
+
is less than four days old. At four days, record **Abandoned - no answer in 4
|
|
108
|
+
days** internally without re-asking, then carry any remaining defect as
|
|
109
|
+
internal work. For legacy replies without disclosure or eyes, search once per
|
|
110
|
+
connected actor and verify the author and thread.
|
|
111
|
+
|
|
112
|
+
End every new or edited Slack reply with the exact sentence
|
|
113
|
+
`this was sent from a bot.`. A connector-added `Sent using ChatGPT` footer is
|
|
114
|
+
not a substitute.
|
|
115
|
+
|
|
116
|
+
Reactions are permanent history and do not replace the internal disposition.
|
|
117
|
+
At the root, `π` records this workflow's claim, `β
` marks one or
|
|
118
|
+
more named scopes that passed direct post-change proof, and `π«` tracks distinct
|
|
119
|
+
human/team actions, including actions with no named owner yet. The eye alone
|
|
120
|
+
does not mean work remains open. One root `β
` covers every verified scope
|
|
121
|
+
listed in `fixedScopes[]`; one root `π«` covers every action listed in
|
|
122
|
+
`handoffs[]`, including unassigned, accepted, and completed actions. Completion
|
|
123
|
+
evidence changes its status, not the historical `π«` reaction. Unclaimed items
|
|
124
|
+
and another actor's marks are not ours to reply to. Reconcile each report as
|
|
125
|
+
one unit: update and read back applicable root reactions before advancing to
|
|
126
|
+
the next report. Add `β
` once a reported scope passes the direct post-change proof bar on `main`.
|
|
127
|
+
An open PR never gets `β
`. Use
|
|
128
|
+
**Partially fixed** for the internal disposition when another scope remains.
|
|
129
|
+
Do not wait for an entire multi-symptom report to be resolved before checking
|
|
130
|
+
off its verified scope. Keep all existing reactions after scopes close. Read
|
|
131
|
+
back every reaction and any reply sent. Never remove or clean up any reaction.
|
|
132
|
+
While a fix PR is open, `π` may remain; `β
` still waits for the merge to `main`.
|
|
133
|
+
The marks are independent. The current disposition says what remains.
|
|
134
|
+
For UI behavior, a focused
|
|
135
|
+
regression qualifies only if it exercises the changed component and asserts the
|
|
136
|
+
reported visible result or persisted state; callback-only assertions, mocked
|
|
137
|
+
children, class-name checks, and source inspection do not. For clipping,
|
|
138
|
+
wrapping, contrast, or alignment, inspect rendered geometry at the reported
|
|
139
|
+
viewport or replay the flow in the running app. Use an app/preview replay when
|
|
140
|
+
the regression does not meet that bar. For non-UI scopes, use the area-specific
|
|
141
|
+
action, query, or test proof. Record merge or rollout state in the internal
|
|
142
|
+
inventory; the checkmark records a verified scope and does not claim it is
|
|
143
|
+
shipped or live.
|
|
144
|
+
Before leaving each report, compare verified scopes and human/team handoffs
|
|
145
|
+
with a fresh root-reaction read. Ensure one `β
` is present when any scope is fixed on `main`, and one `π«` whenever any distinct unfinished action requires another
|
|
146
|
+
person or team to act, even before ownership is assigned or accepted. Keep the
|
|
147
|
+
mark as history after completion; read back each changed root reaction and
|
|
148
|
+
verify its owner. Record whether each mark applies and any historical-reaction
|
|
149
|
+
details in the internal inventory only; never explain missing reactions in a
|
|
150
|
+
reporter reply. Emoji text in a reply is not a reaction. Preserve every
|
|
151
|
+
existing reaction. If later proof invalidates a prior checkmark, move that
|
|
152
|
+
scope out of active `fixedScopes[]` and add a `historicalReactionMarks[]` entry
|
|
153
|
+
with `emoji`, `scope`, `reason`, and the exact prior `previousStatus`. If the
|
|
154
|
+
owner withdraws an accepted action tracked by `π«`, preserve the exact earlier
|
|
155
|
+
accepted `handoff` and owner `withdrawalReply`, then update the internal record.
|
|
156
|
+
Keep these records consistent with the captured thread; never remove
|
|
157
|
+
or clean up a reaction.
|
|
158
|
+
Add `π«` for each distinct unfinished team or engineering action that another
|
|
159
|
+
person or team must perform outside this workflow, whether or not a named
|
|
160
|
+
person has accepted it or an external tracker ticket exists. Record each such
|
|
161
|
+
action in `handoffs[]`
|
|
162
|
+
with its exact scope, action, and responsible person or team. A team or role owner, or no owner
|
|
163
|
+
at all, keeps `status: "unassigned"` until a named person commits. Another person's
|
|
164
|
+
reply never changes an existing named owner. Do not invent a
|
|
165
|
+
person, Slack ID, request, or acceptance. A handoff becomes `accepted` only when a named person makes an explicit first-person
|
|
166
|
+
commitment to the recorded action in the thread. That person becomes its owner: record
|
|
167
|
+
their Slack ID and exact reply, and change the status to
|
|
168
|
+
`"accepted"`; when the accepted action is done, use `status: "completed"` with
|
|
169
|
+
completion evidence. The `π«` reaction remains as history after completion and
|
|
170
|
+
no longer counts as an open blocker. An owner withdrawal sets the handoff back to `status: "unassigned"` and keeps it in
|
|
171
|
+
`handoffs[]` with its `π«`, so unfinished work stays tracked. It leaves current
|
|
172
|
+
handoffs only when the action is completed. An
|
|
173
|
+
unambiguous contextual βyesβ/βsureβ may accept a
|
|
174
|
+
preceding direct request when it names the human and exact action. That request
|
|
175
|
+
may ask whether the named person's TODO or PR already includes the action; a
|
|
176
|
+
clear βyes, it's on my PRβ with a stated next step such as βtaking a look nowβ
|
|
177
|
+
counts. Record both
|
|
178
|
+
the request and acceptance reply, including timestamps and actor IDs. The
|
|
179
|
+
human's explicit first-person commitment to the recorded action also counts,
|
|
180
|
+
even without a preceding request (for example, βI'll test this todayβ or βI'll
|
|
181
|
+
expand it to all appsβ). Record that exact acceptance reply. Tentative language
|
|
182
|
+
such as βI might test thisβ is not acceptance. Keep acceptance and refusal verbs
|
|
183
|
+
consistent with the examples in this file.
|
|
184
|
+
The `π«` reaction covers only that recorded action: do not infer a broader fix,
|
|
185
|
+
PR, or delivery promise. A role assignment, generic team ping, or ask without a reply
|
|
186
|
+
is not acceptance, but it still gets `π«` when a distinct team action remains
|
|
187
|
+
unfinished. Ambiguous or hedged assent does not change `status: "unassigned"`.
|
|
188
|
+
A partial fix with a separately unfinished human/team action can have both
|
|
189
|
+
`β
` and `π«`.
|
|
190
|
+
Work that remains with this workflow is active and needs no `π«` by itself, but a fix
|
|
191
|
+
this workflow could not land gets `π«` as a human handoff, matching the parent skill.
|
|
192
|
+
Requests for a reporter-provided URL, evidence, or clarification are separate human
|
|
193
|
+
actions, not team handoffs. Access, credentials, admin rights, and account changes
|
|
194
|
+
are never asked of the reporter. They are Steve's internal work: record them in `handoffs[]` with a `π«`, owner `"unassigned"`,
|
|
195
|
+
and `status: "unassigned"` until Steve explicitly commits in the thread; name Steve in
|
|
196
|
+
the action text, not the owner field. They
|
|
197
|
+
are not in `reporterRequests[]`, so they do not expire with the reporter-request
|
|
198
|
+
lifecycle.
|
|
199
|
+
When this workflow asks a reporter for a URL, evidence, or clarification,
|
|
200
|
+
record the requested action in `reporterRequests[]` and add/read back `π«` while
|
|
201
|
+
that request is open. This tracks a requested human action; it is not a team
|
|
202
|
+
handoff and does not claim accepted ownership. When the reporter answers, or
|
|
203
|
+
after four days with no later human reply, move it out of active
|
|
204
|
+
`reporterRequests[]` and preserve the root mark in `historicalReactionMarks[]`.
|
|
205
|
+
Keep its original `scope`, `action`, `requestReply`, and ticket-bearing
|
|
206
|
+
`previousStatus` under `closedReporterRequest`. For an answer, set
|
|
207
|
+
`resolution: "answered"` and include the exact human `closureReply` from the
|
|
208
|
+
same thread. For an unanswered request,
|
|
209
|
+
set `resolution: "abandoned_no_answer"` only after four days with no later human
|
|
210
|
+
reply, and omit `closureReply`. Keep the historical action and its evidence in
|
|
211
|
+
the internal inventory. Link an external tracker ticket only
|
|
212
|
+
if one already exists; do not create or promise one without authorization. If a
|
|
213
|
+
human later refuses the accepted action, preserve `π«` as history and record
|
|
214
|
+
the refusal and blocker in the internal inventory.
|
|
215
|
+
|
|
216
|
+
Use the same connected Slack identity for reactions, replies, and read-back.
|
|
217
|
+
Compare exact actor IDs returned for the reaction and reply; do not describe a
|
|
218
|
+
separate βworkflow identityβ when the connector posts as the invoking user. An
|
|
219
|
+
explicit handoff from another eye owner permits investigation only; it does
|
|
220
|
+
not transfer the eye or authorize changing that actor's reactions. If the eye
|
|
221
|
+
owner differs from the connected actor, or an actor ID cannot be verified,
|
|
222
|
+
record the mismatch internally and leave the item unreconciled for its owner.
|
|
223
|
+
Do not claim that eye or create a duplicate reply under another actor.
|
|
224
|
+
Never remove or clean up another person's or this workflow's reaction. When
|
|
225
|
+
new evidence changes the meaning of an existing mark, preserve it and update
|
|
226
|
+
the internal disposition and inventory. Read back every new reaction and reply.
|
|
227
|
+
|
|
228
|
+
An unanswered request for a reporter-provided URL, evidence, or
|
|
229
|
+
clarification is **Asked** or **Clarification needed** and remains an open
|
|
230
|
+
requested human action: record it in `reporterRequests[]`, keep `π`, and
|
|
231
|
+
add/read back `π«`. Ask the direct question in the short reply that accompanies
|
|
232
|
+
the new `π«`. It is not a team handoff, so it does not require or imply an
|
|
233
|
+
accepted owner in `handoffs[]`.
|
|
234
|
+
When no other person needs to act and only this workflow owns the next step, do
|
|
235
|
+
not add `π«`.
|
|
236
|
+
|
|
237
|
+
Resolve duplicate clusters before claiming. Record non-owner duplicates by
|
|
238
|
+
permalink and **Clustered** in the internal inventory; do not send a status
|
|
239
|
+
reply solely to report clustering. For a late duplicate that already has `π`,
|
|
240
|
+
recheck ownership. If this task still owns it, keep the eye and record its
|
|
241
|
+
owner permalink; do not send a second owner update. If another task owns it or
|
|
242
|
+
ownership is unclear, preserve the eye, record the source in your run notes, and
|
|
243
|
+
stop. Keep
|
|
244
|
+
distinct scopes and their status clear.
|
|
245
|
+
|
|
246
|
+
Compare each reported symptom with the evidence in the internal inventory.
|
|
247
|
+
Use one root `β
` when at least one fixed scope is merged to `main` and verified; it covers every
|
|
248
|
+
verified scope listed in `fixedScopes[]`, with proof recorded internally. Use
|
|
249
|
+
one root `π«` whenever at least one distinct unfinished action
|
|
250
|
+
requires another person to act; it covers the actions listed in `handoffs[]`
|
|
251
|
+
and active requests in `reporterRequests[]`. Handoffs include unassigned
|
|
252
|
+
actions and completed actions whose evidence and `status: "completed"` remain
|
|
253
|
+
in your run notes; reporter requests stay active only while the requested input is
|
|
254
|
+
outstanding.
|
|
255
|
+
Do not add duplicate copies of either reaction for additional scopes. Link an
|
|
256
|
+
external tracker ticket if there is one. Record a person's Slack ID and exact reply
|
|
257
|
+
only after that person accepts; until then record the responsible team/role or
|
|
258
|
+
`unassigned` and set `status: "unassigned"`. Keep `π` while work remains. An open reporter request gets `π«` even though it is not a team handoff; a
|
|
259
|
+
team handoff also gets `π«`. Do not create or promise an external tracker
|
|
260
|
+
ticket without authorization. Never imply a
|
|
261
|
+
partial fix resolved the whole report.
|
|
262
|
+
|
|
263
|
+
For beta and package fixes, verify publisher and release state and keep the
|
|
264
|
+
details in the internal recap. Do not send progress or deployment narration.
|
|
265
|
+
If this run adds a reaction, explain only that new reaction in the short reply.
|
|
266
|
+
Keep technical details, IDs, CI, workflow details, and run IDs out of reporter
|
|
267
|
+
replies.
|
|
268
|
+
|
|
269
|
+
For every reply in each final full-thread snapshot, record a read-back of the
|
|
270
|
+
workflow reactions on that reply. If the connector shows `π`, `β
`, or `π«`,
|
|
271
|
+
call `slack_get_reactions` for the reply's own timestamp and record exact owner
|
|
272
|
+
IDs for those workflow emoji; record `"none"` with `{}` when none appears and
|
|
273
|
+
omit unrelated emoji. These reads are separate from the root read-back. Do not
|
|
274
|
+
add new workflow reactions to replies. Preserve any legacy reply-level mark and
|
|
275
|
+
record its exact message timestamp and owner; then audit the report root
|
|
276
|
+
independently. A reply mark never checks off the root scope. Keep it attributed; never move
|
|
277
|
+
or remove it.
|
|
278
|
+
|
|
279
|
+
Read back the reaction and any reply through the same connector, and verify
|
|
280
|
+
their actor IDs match the recorded sweep identity before recording the item as
|
|
281
|
+
replied. Keep the full mark, scope, and action inventory internally. In the
|
|
282
|
+
user-facing recap, mention only reactions added in this run and explain them
|
|
283
|
+
briefly. Do not explain absent or unchanged reactions or whether a tracker
|
|
284
|
+
ticket exists. Keep any existing ticket link in the internal inventory. Do not
|
|
285
|
+
balance reactions for appearance. Treat
|
|
286
|
+
reaction text in a reply, another actor's mark, or a reply-row reaction as no
|
|
287
|
+
substitute for the required root read-back.
|
|
@@ -423,6 +423,29 @@ invocation explicitly authorizes that communication on the exact PR. This does
|
|
|
423
423
|
not add a separate authorization step for replies required on the active
|
|
424
424
|
user's own PR under `/ship`, `/ship-now`, or `/babysit-pr`.
|
|
425
425
|
|
|
426
|
+
When a PR needs product, UX, or app-owner review, record that gate only in the
|
|
427
|
+
recap and leave the PR thread alone. Do not comment or reply to ask for, announce,
|
|
428
|
+
or explain that owner review is needed. This silence rule applies even after an
|
|
429
|
+
author update; do not send a thanks-only or status reply while that review gate is
|
|
430
|
+
outstanding.
|
|
431
|
+
This silence rule does not suppress replies required on the active user's own PR
|
|
432
|
+
under `/ship`, `/ship-now`, or `/babysit-pr`; those follow the own-PR reply rules.
|
|
433
|
+
|
|
434
|
+
When a reply is needed to resolve a review thread on the exact PR the current
|
|
435
|
+
invocation authorizes, only a verified external author gets one. Confirm the author
|
|
436
|
+
is a nonmember first. An unknown-membership author gets no reply, and the membership
|
|
437
|
+
check goes in the recap. Verified BuilderIO members get no reply here. The active
|
|
438
|
+
user's own PR is the one exception: it gets the disposition only, with no thank-you.
|
|
439
|
+
For a verified external author, an explicit reply request sends the reply even
|
|
440
|
+
without an author update. Otherwise reply only if the author has updated since the
|
|
441
|
+
last message, and begin by thanking them for the PR or for their update. An explicit
|
|
442
|
+
request does not override the owner-review silence rule above, except on the active
|
|
443
|
+
user's own PR. Never write βI have no further feedbackβ or another vague closing;
|
|
444
|
+
state the disposition and the next actor and action, such as the exact change
|
|
445
|
+
requested, that no changes are requested and the PR is ready for maintainer
|
|
446
|
+
merge, or which named check is still pending. If the next step is a product,
|
|
447
|
+
UX, or app-owner decision, use the silence rule above.
|
|
448
|
+
|
|
426
449
|
Bot-authored PRs, including Dependabot, are outside this skill's review and
|
|
427
450
|
merge scope and must remain completely untouched.
|
|
428
451
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.222.0
|
|
3
|
+
"version": "0.222.0",
|
|
4
4
|
"description": "The agentic application framework for building autonomous agents with intuitive UIs",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -742,8 +742,8 @@
|
|
|
742
742
|
"yaml": "^2.9.0",
|
|
743
743
|
"yjs": "^13.6.33",
|
|
744
744
|
"zod": "^4.3.6",
|
|
745
|
-
"@agent-native/agentkit": "^0.222.0
|
|
746
|
-
"@agent-native/recap-cli": "^0.5.
|
|
745
|
+
"@agent-native/agentkit": "^0.222.0",
|
|
746
|
+
"@agent-native/recap-cli": "^0.5.91"
|
|
747
747
|
},
|
|
748
748
|
"devDependencies": {
|
|
749
749
|
"@ai-sdk/anthropic": "^3.0.71",
|
|
@@ -814,7 +814,7 @@
|
|
|
814
814
|
"xlsx": "^0.18.5"
|
|
815
815
|
},
|
|
816
816
|
"peerDependencies": {
|
|
817
|
-
"@agent-native/core-corpus": "0.
|
|
817
|
+
"@agent-native/core-corpus": ">=0.196.0",
|
|
818
818
|
"@ai-sdk/anthropic": ">=3",
|
|
819
819
|
"@ai-sdk/cohere": ">=3",
|
|
820
820
|
"@ai-sdk/google": ">=3",
|
|
@@ -21,6 +21,10 @@ not judged by ledgers, receipts, or checker output, so don't produce them.
|
|
|
21
21
|
|
|
22
22
|
## The contract
|
|
23
23
|
|
|
24
|
+
The detailed Slack reaction and reply rules are in
|
|
25
|
+
[slack-reaction-replies.md](references/slack-reaction-replies.md); read it before
|
|
26
|
+
marking, replying to, or closing any Slack report.
|
|
27
|
+
|
|
24
28
|
Slack reactions on a report's root message mean exactly this:
|
|
25
29
|
|
|
26
30
|
| Mark | Meaning | When to add |
|
|
@@ -43,7 +47,8 @@ might need to take back. Every π you add ends the run with a reply, plus
|
|
|
43
47
|
either β
or π«, or a fix PR that is still open and lists the report (its
|
|
44
48
|
merge adds the β
). A π with no follow-up is the most common complaint about this workflow.
|
|
45
49
|
|
|
46
|
-
Every claimed report gets **one** reply in its thread per outcome.
|
|
50
|
+
Every claimed report gets **one** reply in its thread per outcome. The one exception is
|
|
51
|
+
the merged `β
` close-out after an in-review reply, which gets no second reply. People
|
|
47
52
|
have pushed back on replies that were long, technical, condescending, vague
|
|
48
53
|
about who does what next, or that handed them work. Each reply must be:
|
|
49
54
|
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Slack Reaction Replies
|
|
2
|
+
|
|
3
|
+
Use the connected Slack integration for every Slack read and write. Never use a browser, screenshots, or UI automation to operate Slack.
|
|
4
|
+
|
|
5
|
+
At sweep exit, reconcile every report root in the scoped inventory that has
|
|
6
|
+
this task's `π`, `β
`, or `π«`, including marks left by earlier runs. Capture
|
|
7
|
+
the exact Slack actor ID used by the connected tool at sweep start. A mark is
|
|
8
|
+
owned by this task only when its reaction owner ID matches that actor ID and the
|
|
9
|
+
root is the workflow's by the parent skill's evidence: a bot-disclosure reply from
|
|
10
|
+
that account, or a root listed under "Claimed, not yet answered" in memory.md. A
|
|
11
|
+
matching reaction without that evidence is a manual mark: leave it alone. Keep
|
|
12
|
+
the disposition, evidence, scopes, and human actions in the internal inventory.
|
|
13
|
+
Post a reporter reply when this run adds a root reaction, when a newer human reporter
|
|
14
|
+
message needs a direct answer, or when this workflow owns a root from an earlier run
|
|
15
|
+
that has no verified reply in its thread yet, unless a person is already handling the root
|
|
16
|
+
or has asked the workflow to stop. The reply is one short, plain-language
|
|
17
|
+
sentence (about 25 words at most), plus the exact bot disclosure, which does not count toward
|
|
18
|
+
that limit. If the root asks a question, that sentence answers
|
|
19
|
+
it first and also explains only the reaction(s) added in this run. An answer to a newer human message
|
|
20
|
+
answers only that message. Skip the reply when the only reaction added is the merged
|
|
21
|
+
`β
` close-out after an earlier "in review" reply; that close-out gets no second
|
|
22
|
+
reply. Do not send progress, merge, or deployment updates. Never explain absent or
|
|
23
|
+
unchanged reactions or whether a tracker ticket exists. If reporter input is
|
|
24
|
+
needed, add `π«` and ask one direct question in that reply. Read back each new
|
|
25
|
+
reaction and reply.
|
|
26
|
+
|
|
27
|
+
Keep prior replies as history. Do not edit or add a status reply merely to
|
|
28
|
+
describe changed evidence, an existing reaction, or completed follow-up work.
|
|
29
|
+
When a new reaction is added, use one short sentence plus the exact bot
|
|
30
|
+
disclosure.
|
|
31
|
+
|
|
32
|
+
When editing an ordinary Slack reply, pass its visible body as
|
|
33
|
+
`message.markdown_text` to `slack_edit_message`; `message.text` is a fallback
|
|
34
|
+
for structured block messages and may leave the visible reply unchanged. Treat
|
|
35
|
+
the returned message ID as acknowledgment only. Read the exact reply back with
|
|
36
|
+
`slack_read_thread` and compare the stored body to the intended status before
|
|
37
|
+
counting it as posted. Use `slack_send_message` only when a new reply is
|
|
38
|
+
needed, with its `message` field and the root `thread_ts`.
|
|
39
|
+
|
|
40
|
+
`slack_read_thread` may append a synthetic `Status marks:` summary after the
|
|
41
|
+
thread. That is connector metadata, not part of any Slack message; do not copy
|
|
42
|
+
it into a reply. Likewise, omit connector-added `Sent using ChatGPT` footer
|
|
43
|
+
text from the intended body. `slack_send_message` may append that footer to a
|
|
44
|
+
new reply; if it does, remove it by editing with `message.markdown_text`, then
|
|
45
|
+
read the reply back again. Include the exact bot disclosure in the visible body
|
|
46
|
+
yourself; the connector footer is not a substitute.
|
|
47
|
+
|
|
48
|
+
Apply reactions to the report root, not the status reply: call
|
|
49
|
+
`slack_add_reaction` with the root's `channel_id`, its timestamp as
|
|
50
|
+
`message_ts`, and the emoji name without colons (`eyes`, `white_check_mark`, or
|
|
51
|
+
`ticket`). A colon-coded emoji mentioned in reply text does not add a reaction.
|
|
52
|
+
After each reaction call, read the root with `slack_get_reactions` and verify
|
|
53
|
+
the intended emoji and this actor's ID are present before recording it or
|
|
54
|
+
moving to another report. A successful tool response is only an acknowledgment;
|
|
55
|
+
the readback is the proof. If a reaction cannot be reconciled, record the exact
|
|
56
|
+
blocker instead of treating the reply text as a substitute.
|
|
57
|
+
|
|
58
|
+
Channel reads may expose a thread reply as a separate row. Resolve its
|
|
59
|
+
`thread_ts` or permalink and inventory it as a reply to the root, not as a new
|
|
60
|
+
report. Put new reactions for an ordinary report on its root; do not add another
|
|
61
|
+
`π` to a reply just because it appears as a channel row. Preserve any legacy
|
|
62
|
+
reaction already on a reply, read it back, and reconcile the actual root
|
|
63
|
+
separately. A reply that raises a genuinely distinct issue stays in the source
|
|
64
|
+
manifest as a reply row, but scope, disposition, handoff, and checkoff evidence
|
|
65
|
+
belong to the actual root row. Record the distinct issue as a separate scope on
|
|
66
|
+
that root and verify it independently. Do not invent a second root or put a
|
|
67
|
+
root checkoff on the reply. Record both the source message timestamp and root
|
|
68
|
+
thread timestamp; if the connector hides `thread_ts`, resolve the permalink
|
|
69
|
+
before recording it.
|
|
70
|
+
|
|
71
|
+
The parent inventory must retain the reaction-owner IDs and the same-parent
|
|
72
|
+
reply timestamp, author ID, disposition, evidence, and read-back text for every
|
|
73
|
+
root this actor marks with `π`, `β
`, or `π«`. Record an explicit decision for
|
|
74
|
+
both `β
` and `π«` on every such root: `present` with its scope, or `none` with
|
|
75
|
+
the reason no mark applies. Record verified fixed scopes with their proof and
|
|
76
|
+
each distinct human handoff with its scope, owner, and action. Before the recap, reconcile every owned root in the inventory by hand. Incomplete
|
|
77
|
+
source coverage or owned-root reconciliation means the sweep is not done. For
|
|
78
|
+
explicitly narrowed scope, keep the active user request as a separate record in
|
|
79
|
+
the inventory. This step does not authorize
|
|
80
|
+
changing another actor's reactions or replies.
|
|
81
|
+
|
|
82
|
+
## Prior questions and reporter replies
|
|
83
|
+
|
|
84
|
+
At sweep start, search the exact bot disclosure in each scoped channel and
|
|
85
|
+
exhaust the pages to find prior questions and their context:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
slack_search: "this was sent from a bot." in:<#CHANNEL>
|
|
89
|
+
sort=timestamp sort_dir=asc include_context=true max_context_length=300
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Also scan channel messages from the saved reply cursor; on the first run, scan
|
|
93
|
+
available history. Since `after:` is date-only, start one day before the cursor,
|
|
94
|
+
exhaust pages, resolve hits to their root, and advance the cursor only through
|
|
95
|
+
processed messages. Read inherited threads carrying any of this actor's root marks (`π`, `β
`,
|
|
96
|
+
or `π«`): a checkmark closes only its verified scope, not a newer reporter
|
|
97
|
+
answer or another open scope. Do not reply or react on another actor's root
|
|
98
|
+
when work is handed off for investigation; that handoff permits local
|
|
99
|
+
investigation only. A separate explicit authorization is required to post a
|
|
100
|
+
reporter-facing reply or change that actor's reactions.
|
|
101
|
+
|
|
102
|
+
Count an answer only when a human posts after the question, without this
|
|
103
|
+
workflow's disclosure, and the reply addresses it. Read the full thread to
|
|
104
|
+
exclude partial, unrelated, or deferred answers; a newer human post reopens the
|
|
105
|
+
question. Attempt the fix with new evidence before asking again. Do not send a
|
|
106
|
+
progress reply when no reaction is added. Do not ask again while the question
|
|
107
|
+
is less than four days old. At four days, record **Abandoned - no answer in 4
|
|
108
|
+
days** internally without re-asking, then carry any remaining defect as
|
|
109
|
+
internal work. For legacy replies without disclosure or eyes, search once per
|
|
110
|
+
connected actor and verify the author and thread.
|
|
111
|
+
|
|
112
|
+
End every new or edited Slack reply with the exact sentence
|
|
113
|
+
`this was sent from a bot.`. A connector-added `Sent using ChatGPT` footer is
|
|
114
|
+
not a substitute.
|
|
115
|
+
|
|
116
|
+
Reactions are permanent history and do not replace the internal disposition.
|
|
117
|
+
At the root, `π` records this workflow's claim, `β
` marks one or
|
|
118
|
+
more named scopes that passed direct post-change proof, and `π«` tracks distinct
|
|
119
|
+
human/team actions, including actions with no named owner yet. The eye alone
|
|
120
|
+
does not mean work remains open. One root `β
` covers every verified scope
|
|
121
|
+
listed in `fixedScopes[]`; one root `π«` covers every action listed in
|
|
122
|
+
`handoffs[]`, including unassigned, accepted, and completed actions. Completion
|
|
123
|
+
evidence changes its status, not the historical `π«` reaction. Unclaimed items
|
|
124
|
+
and another actor's marks are not ours to reply to. Reconcile each report as
|
|
125
|
+
one unit: update and read back applicable root reactions before advancing to
|
|
126
|
+
the next report. Add `β
` once a reported scope passes the direct post-change proof bar on `main`.
|
|
127
|
+
An open PR never gets `β
`. Use
|
|
128
|
+
**Partially fixed** for the internal disposition when another scope remains.
|
|
129
|
+
Do not wait for an entire multi-symptom report to be resolved before checking
|
|
130
|
+
off its verified scope. Keep all existing reactions after scopes close. Read
|
|
131
|
+
back every reaction and any reply sent. Never remove or clean up any reaction.
|
|
132
|
+
While a fix PR is open, `π` may remain; `β
` still waits for the merge to `main`.
|
|
133
|
+
The marks are independent. The current disposition says what remains.
|
|
134
|
+
For UI behavior, a focused
|
|
135
|
+
regression qualifies only if it exercises the changed component and asserts the
|
|
136
|
+
reported visible result or persisted state; callback-only assertions, mocked
|
|
137
|
+
children, class-name checks, and source inspection do not. For clipping,
|
|
138
|
+
wrapping, contrast, or alignment, inspect rendered geometry at the reported
|
|
139
|
+
viewport or replay the flow in the running app. Use an app/preview replay when
|
|
140
|
+
the regression does not meet that bar. For non-UI scopes, use the area-specific
|
|
141
|
+
action, query, or test proof. Record merge or rollout state in the internal
|
|
142
|
+
inventory; the checkmark records a verified scope and does not claim it is
|
|
143
|
+
shipped or live.
|
|
144
|
+
Before leaving each report, compare verified scopes and human/team handoffs
|
|
145
|
+
with a fresh root-reaction read. Ensure one `β
` is present when any scope is fixed on `main`, and one `π«` whenever any distinct unfinished action requires another
|
|
146
|
+
person or team to act, even before ownership is assigned or accepted. Keep the
|
|
147
|
+
mark as history after completion; read back each changed root reaction and
|
|
148
|
+
verify its owner. Record whether each mark applies and any historical-reaction
|
|
149
|
+
details in the internal inventory only; never explain missing reactions in a
|
|
150
|
+
reporter reply. Emoji text in a reply is not a reaction. Preserve every
|
|
151
|
+
existing reaction. If later proof invalidates a prior checkmark, move that
|
|
152
|
+
scope out of active `fixedScopes[]` and add a `historicalReactionMarks[]` entry
|
|
153
|
+
with `emoji`, `scope`, `reason`, and the exact prior `previousStatus`. If the
|
|
154
|
+
owner withdraws an accepted action tracked by `π«`, preserve the exact earlier
|
|
155
|
+
accepted `handoff` and owner `withdrawalReply`, then update the internal record.
|
|
156
|
+
Keep these records consistent with the captured thread; never remove
|
|
157
|
+
or clean up a reaction.
|
|
158
|
+
Add `π«` for each distinct unfinished team or engineering action that another
|
|
159
|
+
person or team must perform outside this workflow, whether or not a named
|
|
160
|
+
person has accepted it or an external tracker ticket exists. Record each such
|
|
161
|
+
action in `handoffs[]`
|
|
162
|
+
with its exact scope, action, and responsible person or team. A team or role owner, or no owner
|
|
163
|
+
at all, keeps `status: "unassigned"` until a named person commits. Another person's
|
|
164
|
+
reply never changes an existing named owner. Do not invent a
|
|
165
|
+
person, Slack ID, request, or acceptance. A handoff becomes `accepted` only when a named person makes an explicit first-person
|
|
166
|
+
commitment to the recorded action in the thread. That person becomes its owner: record
|
|
167
|
+
their Slack ID and exact reply, and change the status to
|
|
168
|
+
`"accepted"`; when the accepted action is done, use `status: "completed"` with
|
|
169
|
+
completion evidence. The `π«` reaction remains as history after completion and
|
|
170
|
+
no longer counts as an open blocker. An owner withdrawal sets the handoff back to `status: "unassigned"` and keeps it in
|
|
171
|
+
`handoffs[]` with its `π«`, so unfinished work stays tracked. It leaves current
|
|
172
|
+
handoffs only when the action is completed. An
|
|
173
|
+
unambiguous contextual βyesβ/βsureβ may accept a
|
|
174
|
+
preceding direct request when it names the human and exact action. That request
|
|
175
|
+
may ask whether the named person's TODO or PR already includes the action; a
|
|
176
|
+
clear βyes, it's on my PRβ with a stated next step such as βtaking a look nowβ
|
|
177
|
+
counts. Record both
|
|
178
|
+
the request and acceptance reply, including timestamps and actor IDs. The
|
|
179
|
+
human's explicit first-person commitment to the recorded action also counts,
|
|
180
|
+
even without a preceding request (for example, βI'll test this todayβ or βI'll
|
|
181
|
+
expand it to all appsβ). Record that exact acceptance reply. Tentative language
|
|
182
|
+
such as βI might test thisβ is not acceptance. Keep acceptance and refusal verbs
|
|
183
|
+
consistent with the examples in this file.
|
|
184
|
+
The `π«` reaction covers only that recorded action: do not infer a broader fix,
|
|
185
|
+
PR, or delivery promise. A role assignment, generic team ping, or ask without a reply
|
|
186
|
+
is not acceptance, but it still gets `π«` when a distinct team action remains
|
|
187
|
+
unfinished. Ambiguous or hedged assent does not change `status: "unassigned"`.
|
|
188
|
+
A partial fix with a separately unfinished human/team action can have both
|
|
189
|
+
`β
` and `π«`.
|
|
190
|
+
Work that remains with this workflow is active and needs no `π«` by itself, but a fix
|
|
191
|
+
this workflow could not land gets `π«` as a human handoff, matching the parent skill.
|
|
192
|
+
Requests for a reporter-provided URL, evidence, or clarification are separate human
|
|
193
|
+
actions, not team handoffs. Access, credentials, admin rights, and account changes
|
|
194
|
+
are never asked of the reporter. They are Steve's internal work: record them in `handoffs[]` with a `π«`, owner `"unassigned"`,
|
|
195
|
+
and `status: "unassigned"` until Steve explicitly commits in the thread; name Steve in
|
|
196
|
+
the action text, not the owner field. They
|
|
197
|
+
are not in `reporterRequests[]`, so they do not expire with the reporter-request
|
|
198
|
+
lifecycle.
|
|
199
|
+
When this workflow asks a reporter for a URL, evidence, or clarification,
|
|
200
|
+
record the requested action in `reporterRequests[]` and add/read back `π«` while
|
|
201
|
+
that request is open. This tracks a requested human action; it is not a team
|
|
202
|
+
handoff and does not claim accepted ownership. When the reporter answers, or
|
|
203
|
+
after four days with no later human reply, move it out of active
|
|
204
|
+
`reporterRequests[]` and preserve the root mark in `historicalReactionMarks[]`.
|
|
205
|
+
Keep its original `scope`, `action`, `requestReply`, and ticket-bearing
|
|
206
|
+
`previousStatus` under `closedReporterRequest`. For an answer, set
|
|
207
|
+
`resolution: "answered"` and include the exact human `closureReply` from the
|
|
208
|
+
same thread. For an unanswered request,
|
|
209
|
+
set `resolution: "abandoned_no_answer"` only after four days with no later human
|
|
210
|
+
reply, and omit `closureReply`. Keep the historical action and its evidence in
|
|
211
|
+
the internal inventory. Link an external tracker ticket only
|
|
212
|
+
if one already exists; do not create or promise one without authorization. If a
|
|
213
|
+
human later refuses the accepted action, preserve `π«` as history and record
|
|
214
|
+
the refusal and blocker in the internal inventory.
|
|
215
|
+
|
|
216
|
+
Use the same connected Slack identity for reactions, replies, and read-back.
|
|
217
|
+
Compare exact actor IDs returned for the reaction and reply; do not describe a
|
|
218
|
+
separate βworkflow identityβ when the connector posts as the invoking user. An
|
|
219
|
+
explicit handoff from another eye owner permits investigation only; it does
|
|
220
|
+
not transfer the eye or authorize changing that actor's reactions. If the eye
|
|
221
|
+
owner differs from the connected actor, or an actor ID cannot be verified,
|
|
222
|
+
record the mismatch internally and leave the item unreconciled for its owner.
|
|
223
|
+
Do not claim that eye or create a duplicate reply under another actor.
|
|
224
|
+
Never remove or clean up another person's or this workflow's reaction. When
|
|
225
|
+
new evidence changes the meaning of an existing mark, preserve it and update
|
|
226
|
+
the internal disposition and inventory. Read back every new reaction and reply.
|
|
227
|
+
|
|
228
|
+
An unanswered request for a reporter-provided URL, evidence, or
|
|
229
|
+
clarification is **Asked** or **Clarification needed** and remains an open
|
|
230
|
+
requested human action: record it in `reporterRequests[]`, keep `π`, and
|
|
231
|
+
add/read back `π«`. Ask the direct question in the short reply that accompanies
|
|
232
|
+
the new `π«`. It is not a team handoff, so it does not require or imply an
|
|
233
|
+
accepted owner in `handoffs[]`.
|
|
234
|
+
When no other person needs to act and only this workflow owns the next step, do
|
|
235
|
+
not add `π«`.
|
|
236
|
+
|
|
237
|
+
Resolve duplicate clusters before claiming. Record non-owner duplicates by
|
|
238
|
+
permalink and **Clustered** in the internal inventory; do not send a status
|
|
239
|
+
reply solely to report clustering. For a late duplicate that already has `π`,
|
|
240
|
+
recheck ownership. If this task still owns it, keep the eye and record its
|
|
241
|
+
owner permalink; do not send a second owner update. If another task owns it or
|
|
242
|
+
ownership is unclear, preserve the eye, record the source in your run notes, and
|
|
243
|
+
stop. Keep
|
|
244
|
+
distinct scopes and their status clear.
|
|
245
|
+
|
|
246
|
+
Compare each reported symptom with the evidence in the internal inventory.
|
|
247
|
+
Use one root `β
` when at least one fixed scope is merged to `main` and verified; it covers every
|
|
248
|
+
verified scope listed in `fixedScopes[]`, with proof recorded internally. Use
|
|
249
|
+
one root `π«` whenever at least one distinct unfinished action
|
|
250
|
+
requires another person to act; it covers the actions listed in `handoffs[]`
|
|
251
|
+
and active requests in `reporterRequests[]`. Handoffs include unassigned
|
|
252
|
+
actions and completed actions whose evidence and `status: "completed"` remain
|
|
253
|
+
in your run notes; reporter requests stay active only while the requested input is
|
|
254
|
+
outstanding.
|
|
255
|
+
Do not add duplicate copies of either reaction for additional scopes. Link an
|
|
256
|
+
external tracker ticket if there is one. Record a person's Slack ID and exact reply
|
|
257
|
+
only after that person accepts; until then record the responsible team/role or
|
|
258
|
+
`unassigned` and set `status: "unassigned"`. Keep `π` while work remains. An open reporter request gets `π«` even though it is not a team handoff; a
|
|
259
|
+
team handoff also gets `π«`. Do not create or promise an external tracker
|
|
260
|
+
ticket without authorization. Never imply a
|
|
261
|
+
partial fix resolved the whole report.
|
|
262
|
+
|
|
263
|
+
For beta and package fixes, verify publisher and release state and keep the
|
|
264
|
+
details in the internal recap. Do not send progress or deployment narration.
|
|
265
|
+
If this run adds a reaction, explain only that new reaction in the short reply.
|
|
266
|
+
Keep technical details, IDs, CI, workflow details, and run IDs out of reporter
|
|
267
|
+
replies.
|
|
268
|
+
|
|
269
|
+
For every reply in each final full-thread snapshot, record a read-back of the
|
|
270
|
+
workflow reactions on that reply. If the connector shows `π`, `β
`, or `π«`,
|
|
271
|
+
call `slack_get_reactions` for the reply's own timestamp and record exact owner
|
|
272
|
+
IDs for those workflow emoji; record `"none"` with `{}` when none appears and
|
|
273
|
+
omit unrelated emoji. These reads are separate from the root read-back. Do not
|
|
274
|
+
add new workflow reactions to replies. Preserve any legacy reply-level mark and
|
|
275
|
+
record its exact message timestamp and owner; then audit the report root
|
|
276
|
+
independently. A reply mark never checks off the root scope. Keep it attributed; never move
|
|
277
|
+
or remove it.
|
|
278
|
+
|
|
279
|
+
Read back the reaction and any reply through the same connector, and verify
|
|
280
|
+
their actor IDs match the recorded sweep identity before recording the item as
|
|
281
|
+
replied. Keep the full mark, scope, and action inventory internally. In the
|
|
282
|
+
user-facing recap, mention only reactions added in this run and explain them
|
|
283
|
+
briefly. Do not explain absent or unchanged reactions or whether a tracker
|
|
284
|
+
ticket exists. Keep any existing ticket link in the internal inventory. Do not
|
|
285
|
+
balance reactions for appearance. Treat
|
|
286
|
+
reaction text in a reply, another actor's mark, or a reply-row reaction as no
|
|
287
|
+
substitute for the required root read-back.
|
|
@@ -423,6 +423,29 @@ invocation explicitly authorizes that communication on the exact PR. This does
|
|
|
423
423
|
not add a separate authorization step for replies required on the active
|
|
424
424
|
user's own PR under `/ship`, `/ship-now`, or `/babysit-pr`.
|
|
425
425
|
|
|
426
|
+
When a PR needs product, UX, or app-owner review, record that gate only in the
|
|
427
|
+
recap and leave the PR thread alone. Do not comment or reply to ask for, announce,
|
|
428
|
+
or explain that owner review is needed. This silence rule applies even after an
|
|
429
|
+
author update; do not send a thanks-only or status reply while that review gate is
|
|
430
|
+
outstanding.
|
|
431
|
+
This silence rule does not suppress replies required on the active user's own PR
|
|
432
|
+
under `/ship`, `/ship-now`, or `/babysit-pr`; those follow the own-PR reply rules.
|
|
433
|
+
|
|
434
|
+
When a reply is needed to resolve a review thread on the exact PR the current
|
|
435
|
+
invocation authorizes, only a verified external author gets one. Confirm the author
|
|
436
|
+
is a nonmember first. An unknown-membership author gets no reply, and the membership
|
|
437
|
+
check goes in the recap. Verified BuilderIO members get no reply here. The active
|
|
438
|
+
user's own PR is the one exception: it gets the disposition only, with no thank-you.
|
|
439
|
+
For a verified external author, an explicit reply request sends the reply even
|
|
440
|
+
without an author update. Otherwise reply only if the author has updated since the
|
|
441
|
+
last message, and begin by thanking them for the PR or for their update. An explicit
|
|
442
|
+
request does not override the owner-review silence rule above, except on the active
|
|
443
|
+
user's own PR. Never write βI have no further feedbackβ or another vague closing;
|
|
444
|
+
state the disposition and the next actor and action, such as the exact change
|
|
445
|
+
requested, that no changes are requested and the PR is ready for maintainer
|
|
446
|
+
merge, or which named check is still pending. If the next step is a product,
|
|
447
|
+
UX, or app-owner decision, use the silence rule above.
|
|
448
|
+
|
|
426
449
|
Bot-authored PRs, including Dependabot, are outside this skill's review and
|
|
427
450
|
merge scope and must remain completely untouched.
|
|
428
451
|
|