Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
376 commits
Select commit Hold shift + click to select a range
c2c9e21
chore(linear): orchestration debug helper for #247
isadeks Jun 9, 2026
7507f38
Merge branch 'feat/247-reconciler' into deploy/247-dev
isadeks Jun 9, 2026
ffcb931
fix(linear): reconciler OOM + reads orchestration_id from nested meta…
isadeks Jun 9, 2026
d63e734
Merge branch 'feat/247-reconciler' into deploy/247-dev
isadeks Jun 9, 2026
fc536f0
test(linear): orchestration integration test vs real createTaskCore (…
isadeks Jun 10, 2026
ab68d16
chore(cdk): cap jest workers + add focused test task (fix OOM)
isadeks Jun 10, 2026
7696ff2
fix(linear): reconciler re-reads before release; document concurrency…
isadeks Jun 10, 2026
79cfb0f
feat(linear): stranded-orchestration backstop (#303)
isadeks Jun 10, 2026
f2052e1
feat(linear): base-branch selection logic for stacked children (#247 A4)
isadeks Jun 10, 2026
9c4a69f
feat(linear): stacked base-branch targeting for child PRs (#247 A4)
isadeks Jun 10, 2026
2c49f58
Merge branch 'feat/247-reconciler' into deploy/247-dev
isadeks Jun 10, 2026
d9e8719
feat(linear): parent rollup comment + stable log events + docs (#247 A5)
isadeks Jun 10, 2026
5cbd6d5
feat(linear): parent rollup comment + stable log events + docs (#247 A5)
isadeks Jun 10, 2026
7abe7ce
Merge branch 'feat/247-reconciler' into deploy/247-dev
isadeks Jun 10, 2026
c0555bd
chore(cdk): untrack.jest-cache (build artifact, already gitignored)
isadeks Jun 10, 2026
efd7dfc
Merge branch 'feat/247-reconciler' into deploy/247-dev
isadeks Jun 10, 2026
642be98
fix(linear): thread base_branch/merge_branches through server invocat…
isadeks Jun 10, 2026
7699ffb
Merge branch 'feat/247-reconciler' into deploy/247-dev
isadeks Jun 10, 2026
1b4fc61
fix(linear): post the parent rollup comment exactly once (#247 A5)
isadeks Jun 10, 2026
6e873b3
fix(linear): post the parent rollup comment exactly once (#247 A5)
isadeks Jun 10, 2026
a7300f9
Merge branch 'feat/247-reconciler' into deploy/247-dev
isadeks Jun 10, 2026
94a491a
fix(screenshot): route preview screenshot to the PR's own Linear issu…
isadeks Jun 10, 2026
86230b9
Merge remote-tracking branch 'upstream/main' into deploy/247-dev
isadeks Jun 10, 2026
c39b452
test(#247): fix pre-existing orchestration test debt surfaced by full…
isadeks Jun 10, 2026
84537b8
fix(agent): repo.py used removed PR_TASK_TYPES after upstream merge
isadeks Jun 10, 2026
222c8fd
fix(agent): enforce provisioned-branch discipline in prompt
isadeks Jun 11, 2026
1b02517
Revert "fix(agent): enforce provisioned-branch discipline in prompt"
isadeks Jun 11, 2026
99b5a17
fix(workflows): repo-bound task w/o workflow_ref → coding/new-task-v1…
isadeks Jun 11, 2026
655d91c
fix(agent): use platform branch_name verbatim — fixes #247 A4 stackin…
isadeks Jun 11, 2026
96c9357
feat(linear): transition + react on the parent epic through orchestra…
isadeks Jun 11, 2026
8277c85
feat(orchestration): make the #247 executor trigger-agnostic (#11)
isadeks Jun 11, 2026
a374fe9
feat(linear): live status block on the parent epic (#247 #3)
isadeks Jun 11, 2026
58cb9d2
fix(linear): parent epic shows only ONE reaction at a time (#247 #3)
isadeks Jun 11, 2026
66b6c13
fix(linear): serialize parent feedback calls to avoid self-throttling…
isadeks Jun 11, 2026
df3f334
docs(adr-001): clarify bottom-up merge + add #247 agent-orchestrated …
isadeks Jun 11, 2026
f4a1ed2
docs(security): document guardrail PROMPT_ATTACK scope + MEDIUM ratio…
isadeks Jun 11, 2026
a616cfa
docs(research): design for orchestration branch maintenance (#305/A6 …
isadeks Jun 11, 2026
aafae71
feat(orchestration): auto-integration node for fan-out leaves (#247 #16)
isadeks Jun 11, 2026
e71dee1
feat(orchestration): ChildBranchIndex GSI + branch lookup (A6 step 1,…
isadeks Jun 12, 2026
75041f3
feat(orchestration): A6 re-stack action + planner (#305 steps 3-4)
isadeks Jun 12, 2026
b77f9e3
feat(orchestration): A6 re-stack detection + processor handler (#305 …
isadeks Jun 12, 2026
1cf3cc2
feat(orchestration): wire A6 restack processor + arm the webhook (#30…
isadeks Jun 12, 2026
0e80d5d
fix(orchestration): A6 resolve dependent PR# from pr_url fallback (#305)
isadeks Jun 12, 2026
498a74b
fix(agent): accept coding/restack-v1 as a PR workflow in param valida…
isadeks Jun 12, 2026
de4ec92
feat(orchestration): link child + integration PRs on the parent rollu…
isadeks Jun 12, 2026
ed10fe6
feat(orchestration): throttle child release to the concurrency budget…
isadeks Jun 12, 2026
e509d88
chore(scripts): add linear_epic.py orchestration stress-test harness
isadeks Jun 12, 2026
c512530
feat(orchestration): planDirectRestack — one-hop cascade core for A6 …
isadeks Jun 12, 2026
b93859e
feat(orchestration): reconciler-driven A6 cascade on iteration/restac…
isadeks Jun 12, 2026
d5938d5
feat(orchestration): Linear comment trigger for A6 re-iteration (#247)
isadeks Jun 12, 2026
65f7558
refactor(orchestration): retire the GitHub pull_request restack path …
isadeks Jun 12, 2026
e59950f
docs(linear): subscribe Comments on the webhook + trim GitHub-usernam…
isadeks Jun 12, 2026
03ab025
feat(blueprint+agent): configurable per-repo build/lint verification …
isadeks Jun 15, 2026
eaf8f1c
feat(agent): warn on the PR when build-regression gating is inert (#1)
isadeks Jun 15, 2026
fc7fb02
docs(developer-guide): document configurable build command + build-ga…
isadeks Jun 15, 2026
9f3d3ac
feat(orchestration): surface A6 cascade on Linear (dependent sub-issu…
isadeks Jun 15, 2026
dbbbe7c
feat(orchestration): extendOrchestration — add sub-issues to a runnin…
isadeks Jun 15, 2026
5a8073c
feat(orchestration): route re-trigger of an existing epic to extend +…
isadeks Jun 15, 2026
3df0933
feat(orchestration): renderEpicPanel — the single maturing panel rend…
isadeks Jun 16, 2026
a96d147
feat(orchestration): upsertEpicPanel + buildPanelRows — shared panel …
isadeks Jun 16, 2026
224e465
feat(orchestration): wire the single maturing panel + retire standalo…
isadeks Jun 16, 2026
a3a02ca
feat(orchestration): reactToComment + replyToComment helpers (#247 UX.3)
isadeks Jun 16, 2026
b2387d0
feat(orchestration): wire @bgagent comment ack — 👀 on receipt, thread…
isadeks Jun 16, 2026
89c2644
feat(orchestration): generalize @bgagent comment trigger to standalon…
isadeks Jun 16, 2026
dd50c29
feat(orchestration): stack new sub-issues on the epic tip, not bare m…
isadeks Jun 16, 2026
eb9efe1
feat(orchestration): failure is a conversation — sanitized reason vs …
isadeks Jun 16, 2026
5466812
fix(orchestration): threaded reply needs issueId, not just parentId (…
isadeks Jun 16, 2026
9f028f4
fix(orchestration): build-fail reply keyed on the real gating signal,…
isadeks Jun 16, 2026
aae0e66
fix(orchestration): friendly node name in the cascade reason (#247 UX…
isadeks Jun 16, 2026
51a4f1b
fix(orchestration): cascade of a no-dependents node must still refres…
isadeks Jun 16, 2026
93db8f6
fix(orchestration): clear rollup claim on cascade re-open so parent s…
isadeks Jun 16, 2026
e99ce50
fix(orchestration): @bgagent thread-reply ack must reply to the threa…
isadeks Jun 17, 2026
48ccc01
merge: upstream/main into deploy/247-dev (Jira #288 + LinearPostResul…
isadeks Jun 17, 2026
14cce82
feat(orchestration): embed the integration node's combined preview in…
isadeks Jun 17, 2026
37a9ad3
fix(agent): pin AgentCore log-delivery resources to deployed identity…
isadeks Jun 17, 2026
a5d00a6
fix(agent): also pin the 2 AgentCore Delivery links (#247 #58 deploy-…
isadeks Jun 17, 2026
08d73de
fix(orchestration): integration node no longer floods the parent epic…
isadeks Jun 17, 2026
834562c
feat(orchestration): route @bgagent comments left on the parent epic …
isadeks Jun 17, 2026
5f08628
fix(orchestration): thread the trigger comment's issue id so a parent…
isadeks Jun 17, 2026
e44cd43
fix(orchestration): idempotency-claim parent-epic comment handling — …
isadeks Jun 17, 2026
d817ab8
fix(orchestration): bot must not trigger on its OWN comments — kill t…
isadeks Jun 17, 2026
0d5c6b0
feat(orchestration): platform settles the comment + sub-issue on iter…
isadeks Jun 17, 2026
d1ce1ec
refactor(agent): make the #58 log-delivery pins an OPT-IN, stack-gate…
isadeks Jun 17, 2026
d68be9e
Merge branch 'main' into deploy/247-dev
isadeks Jun 17, 2026
42a9c83
chore(security): allowlist orchestration idempotencyKey test fixtures…
isadeks Jun 17, 2026
533316c
style(agent): fix ruff lint + format to unblock CI build (#247 PR #373)
isadeks Jun 17, 2026
93a486d
fix(security): don't read the OAuth secret value in the orchestration…
isadeks Jun 17, 2026
5827092
docs(security): mark the orchestration_debug CodeQL alert as a docume…
isadeks Jun 17, 2026
d072709
style(cdk): resolve eslint debt blocking the PR #373 build (#247)
isadeks Jun 17, 2026
7fdda3d
test(cdk): make the _KNOWN_WRITEABLE_WORKFLOW_IDS parser tolerant of …
isadeks Jun 17, 2026
58da79a
docs(adr): ADR-017 — Linear agent-session as a future (flag-gated, po…
isadeks Jun 17, 2026
161d1fa
docs(adr): ADR-017 — record the Agents-API Preview spike findings (UX…
isadeks Jun 17, 2026
3a2456b
docs(adr): ADR-017 — agent-session spike re-run resolves the 10s-vs-l…
isadeks Jun 17, 2026
f241a71
docs(adr): ADR-017 — record that the agent-session toggle is not a no-op
isadeks Jun 17, 2026
200b527
feat(linear): teach agent to fetch attachments + docs via Linear MCP
isadeks May 27, 2026
d41ecad
fix(linear): wire AttachmentsBucket into LinearIntegration
isadeks May 27, 2026
44b3ac3
fix(linear): skip uploads.linear.app images in description pre-fetch
isadeks May 27, 2026
69d1898
fix(linear): teach agent to detect save_issue silent no-ops
isadeks May 27, 2026
f2a9496
style(cdk): extract MAX_HINTED_ATTACHMENT_TITLES const in linear-issu…
isadeks Jun 18, 2026
4eab526
merge: bring #247 orchestration + Linear-MCP attachments onto linear-…
isadeks Jun 18, 2026
a7dd713
merge: bring linear-vercel current with aws-samples/main (66f78bc)
isadeks Jun 18, 2026
386b586
fix(agent): persist build_passed/lint_passed to task record + skip in…
isadeks Jun 18, 2026
ada624b
fix(agent): annotate expr_values dict[str, object] + wrap lint-skip l…
isadeks Jun 18, 2026
419d3a9
fix(orchestration): clear stuck 👀 on disambiguation + smarter no-matc…
isadeks Jun 18, 2026
130b645
fix(agent): run shell-chained verify commands through bash -lc (#72 —…
isadeks Jun 18, 2026
9bb7cca
feat(orchestration): recovery cascade — comment-fix a failed child re…
isadeks Jun 18, 2026
4938b07
fix(orchestration): recovery resets skipped SUBTREE + reopens panel/r…
isadeks Jun 18, 2026
04b0b44
fix(orchestration): recovery must persist skipped→blocked BEFORE rele…
isadeks Jun 18, 2026
eb9f881
perf(orchestration): release ready children in bounded-parallel chunk…
isadeks Jun 21, 2026
8b98a50
Revert "perf(orchestration): release ready children in bounded-parall…
isadeks Jun 21, 2026
a391d38
docs(linear): document adding a sub-issue to a running epic (re-apply…
isadeks Jun 21, 2026
7a01d24
merge: bring linear-vercel current with aws-samples/main (e6ce821)
isadeks Jun 23, 2026
e42df00
docs(adr): renumber Linear agent-session ADR 017→018 (collision with …
isadeks Jun 23, 2026
6317731
feat(linear): #299 Mode B — auto-decompose an issue into a sub-issue …
isadeks Jun 23, 2026
82cfd18
fix(linear): #299 Mode B write-back — relation type is an enum + rest…
isadeks Jun 23, 2026
05a699d
fix(linear): A6 comment-iteration — answer questions, don't fake '✅ U…
isadeks Jun 23, 2026
11ad986
feat(linear): iteration-UX foundation — maturing-reply renderer + thr…
isadeks Jun 23, 2026
543090b
feat(linear): iteration-UX platform side — one maturing reply per rou…
isadeks Jun 23, 2026
718b118
feat(linear): iteration-UX agent side — suppress redundant progress c…
isadeks Jun 23, 2026
102aba5
fix(cdk): iteration-UX running-total — GetItem per task, not a GSI pr…
isadeks Jun 23, 2026
cc6d912
fix(linear): iteration-UX — suppress standalone 🖼️ screenshot comment…
isadeks Jun 23, 2026
5aff058
feat(linear): iteration-UX — clickable PR link in reply + fix screens…
isadeks Jun 24, 2026
489c2d2
fix(linear): iteration-UX — append preview link to the iteration repl…
isadeks Jun 24, 2026
d7f8b81
fix(linear): grant screenshot processor dynamodb:Query on LinearIssue…
isadeks Jun 24, 2026
fbdc53a
fix(linear): converge iteration preview link with terminal-settle (AB…
isadeks Jun 24, 2026
d81d887
fix(linear): iteration preview = clickable image thumbnail, not a dep…
isadeks Jun 24, 2026
38c5fa5
fix(linear): render iteration preview from durable DDB read, not the …
isadeks Jun 24, 2026
c9bb825
feat(#299): two-stage decomposition planner — critical assessor + dec…
isadeks Jun 24, 2026
4089c96
fix(#299): assessor splits on shippable value, not internal parts/bui…
isadeks Jun 25, 2026
4f9ec3d
fix(#299): assessor teaches the general discriminator, not enumerated…
isadeks Jun 25, 2026
7785f19
fix(#299): reframe decompose assessor around the reliability objective
isadeks Jun 25, 2026
20a4fed
fix(#299): agent's assessment decides whether to split — drop forced-…
isadeks Jun 25, 2026
9105a00
feat(slack): channel→repo default mapping (Slack parity F2)
isadeks Jun 25, 2026
472b45d
fix(ux): stress-audit findings — 7 real fixes across Mode B + iterati…
isadeks Jun 25, 2026
251f5ea
fix(ux): clear the audit's deferred-but-real tail (5 fixes)
isadeks Jun 25, 2026
dc34d1b
chore(cdk): auto-reclaim disk before deploy (clean:disk dep) — fix EN…
isadeks Jun 25, 2026
5e4ac17
chore(cdk): gate clean:disk's uv/docker prune on low free disk
isadeks Jun 25, 2026
dbf685a
fix(orch): surface integration-node build failures (debuggability gap)
isadeks Jun 29, 2026
9e2bd45
fix(agent): build-verify timeout reads as 'timed out', not 'build fai…
isadeks Jun 29, 2026
e8a15ef
fix(agent-classifier): recognize 'Agent session error (subtype=…)' wr…
isadeks Jun 29, 2026
fc54da6
feat(agent): stuck/runaway guard — break a repeating-failing-command …
isadeks Jun 29, 2026
ed7445f
docs: cherry-pick manifest for the debuggability arc
isadeks Jun 29, 2026
1043269
feat(linear): mid-run liveness heartbeat on the iteration reply
isadeks Jun 29, 2026
10d0764
docs: mark a fix heartbeat built in the cherry-pick manifest
isadeks Jun 29, 2026
c47e486
fix: heartbeat covers STANDALONE iterations too, not just orchestration
isadeks Jun 29, 2026
32a6e09
fix: heartbeat resolves the reply issue from linear_issue_id for stan…
isadeks Jun 29, 2026
5e9a193
fix: stuck-guard is advisory-only — drop the bail, keep a one-time steer
isadeks Jun 29, 2026
b812e49
fix: post-agent build gate reports INERT (exit 127 / no-such-task), n…
isadeks Jun 29, 2026
2fd5fca
fix: enable corepack in the agent image so yarn/pnpm resolve
isadeks Jun 29, 2026
4757974
docs: manifest — several fixes main-bound, a fix now advisory-only, a…
isadeks Jun 29, 2026
bf66136
Merge remote-tracking branch 'upstream/main' into feat/slack-channel-…
isadeks Jun 29, 2026
8cb7cfa
wire ECS/Fargate substrate (context-gated) at 32GB/8vCPU for heavy bu…
isadeks Jun 29, 2026
11fb3a5
bump ECS Fargate to 64GB/16vCPU + BUILD_VERIFY_TIMEOUT_S=3600
isadeks Jun 29, 2026
82f57f3
fix(ecs): write task payload to S3, not inline overrides (#502)
isadeks Jun 29, 2026
e1a9230
fix(linear): grant screenshot processor dynamodb:GetItem on TaskTable…
isadeks Jun 30, 2026
2329001
fix(linear): harden + document the agent-mode pitfall (comments rende…
isadeks Jul 1, 2026
777ee0e
fix(ecs): map full payload to run_task so channel/build/cedar fields …
isadeks Jul 1, 2026
5a886bb
fix(ecs): grant task role GetSecretValue on bgagent-{linear,jira}-oau…
isadeks Jul 1, 2026
172ec71
test(fix): stop context-hydration flake — delete ambient MEMORY_ID in…
isadeks Jul 1, 2026
f76c2d3
fix(linear): stop Mode B decompose from silently timing out on large …
isadeks Jul 1, 2026
facb90c
fix(linear): give the Mode B decompose assessor repo context (ABCA-492)
isadeks Jul 1, 2026
29b0e01
fix(linear): deepen planner repo context + surface underspecified :de…
isadeks Jul 2, 2026
0017872
feat(#299): P1 — coding/decompose-v1 agent workflow (scaffolding)
isadeks Jul 3, 2026
19c39c0
feat(#299): P2 — decompose-v1 workflow + agent delivers plan as artifact
isadeks Jul 3, 2026
11442b9
feat(#299): agent-native decompose — webhook dispatches plan task, re…
isadeks Jul 3, 2026
274d8e5
refactor(#299): retire the inline decomposition planner (P5 cleanup)
isadeks Jul 3, 2026
db5a1fc
fix(#299): claim-once the decompose plan reconcile (stop duplicate pr…
isadeks Jul 5, 2026
44522e7
fix(#299): parse the plan even when the agent's message has braces be…
isadeks Jul 5, 2026
d9e6c7b
feat(#299): interactive revise loop — deny a plan with feedback → re-…
isadeks Jul 6, 2026
f0c51ed
fix(#299): stop planning-thread clutter + garbage revision run (3 bug…
isadeks Jul 6, 2026
ba12771
fix(#299): revise feedback no longer trips the content-policy guardra…
isadeks Jul 6, 2026
118bc24
feat(linear): first-time-user UX — labels help, plain-English plans, …
isadeks Jul 6, 2026
96ebaf1
fix(agent): sharpen clarify-before-spend to catch bare quality/goal a…
isadeks Jul 6, 2026
2135efe
feat(agent): clarify-before-spend via a deterministic request_clarifi…
isadeks Jul 6, 2026
a83d090
fix(orchestrator): pin read-only workflows to agentcore compute + hon…
isadeks Jul 6, 2026
d1613a4
fix(orchestrator): planning inherits repo compute; honest decompose-f…
isadeks Jul 6, 2026
7617d72
fix(ecs): wire ARTIFACTS_BUCKET_NAME into the Fargate task (ECS-parit…
isadeks Jul 6, 2026
cb7c8c6
feat(compute): guard compute_type=ecs against a stack without the ECS…
isadeks Jul 6, 2026
a2e80db
fix(decompose): revise-loop QA batch — reject-guard, over-cap, nudge,…
isadeks Jul 6, 2026
f63b90b
fix(decompose): second PM QA batch — clarify-resume, mention word, si…
isadeks Jul 6, 2026
cc077da
fix(decompose): close the short-negation-with-instruction gap (T1, li…
isadeks Jul 6, 2026
f524f8c
feat(decompose): direct-manipulation command grammar for pending plan…
isadeks Jul 7, 2026
665414f
feat(decompose): mature the plan comment in place on structural comma…
isadeks Jul 7, 2026
37c2ada
feat(decompose): warm repo digest — cache exploration across revise r…
isadeks Jul 7, 2026
e038d69
fix(fanout): render the PR link on ✅ success, not only on ⚠️ (F-prlink)
isadeks Jul 7, 2026
a8632ff
feat(decompose): gate :decompose→single-task behind approval (F-singl…
isadeks Jul 7, 2026
1d57a11
feat(decompose): semantic revise matures the plan comment in place + …
isadeks Jul 7, 2026
c5c71b2
docs(decompose): plan-mode design + merge-handoff docs (+ Starlight m…
isadeks Jul 7, 2026
12c7a4a
chore(docs): tidy comment attributions + remove transient manifest
isadeks Jul 7, 2026
2f63ad5
fix(#299): self-merge no longer corrupts the plan + dedup duplicate d…
isadeks Jul 7, 2026
1bf5392
fix(#299): revise edits the current plan (visible diff) + wrong-menti…
isadeks Jul 7, 2026
5e9d410
fix(#299): kill the silent :auto window, board-state on decompose, cl…
isadeks Jul 7, 2026
a2fb58e
fix(#299): revise EDITS the current plan deterministically (no re-der…
isadeks Jul 8, 2026
7255219
fix(#299): settle 👀 on plan commands + revert :decompose to not-start…
isadeks Jul 8, 2026
ad05148
feat(#299): right-size ECS decompose planning onto a smaller Fargate …
isadeks Jul 8, 2026
2c31b97
docs(#299): document decompose plan-first mode + ECS right-sized plan…
isadeks Jul 8, 2026
8304221
fix(#299): move cdk-nag suppressions onto the shared ECS roles (was b…
isadeks Jul 8, 2026
6e4151b
fix(#299): skip the pre-agent build/lint baseline for read-only workf…
isadeks Jul 8, 2026
385e32f
fix(#299): persona-stress decompose findings — revise visibility + co…
isadeks Jul 8, 2026
4bc412c
fix(#299): revert escalated-revise issue from In Progress once the re…
isadeks Jul 8, 2026
def0076
test(#299): AgentStack ECS gate now provisions both task defs (build …
isadeks Jul 8, 2026
21a5d4a
fix(#299): decompose names its assumption on an ambiguous target (PM …
isadeks Jul 8, 2026
b3e49c5
fix(#247): ECS RunTask on task-def FAMILY (deploy-race) + retry-vs-es…
isadeks Jul 8, 2026
63a12dc
feat(errors): 3-way transient/service/user classification + auto-retr…
isadeks Jul 8, 2026
6394a59
fix(errors): classify a build/verify command TIMEOUT (live-caught ABC…
isadeks Jul 8, 2026
b7bec9a
feat(#299): converge decompose thread on Mode-A shape — frozen plan r…
isadeks Jul 8, 2026
4a85c6b
fix(#247): re-trigger a terminal epic RETRIES its failed/skipped chil…
isadeks Jul 8, 2026
a2f9c51
fix(#247): epic retry must salt the idempotency key with the prior ta…
isadeks Jul 8, 2026
676da58
fix(#247): epic-retry UX — dedup the retry note + reposition the live…
isadeks Jul 8, 2026
3d84879
Merge remote-tracking branch 'upstream/main' into fix/492-decompose-r…
isadeks Jul 8, 2026
dd8b2d5
fix(#247): reconcile a build-failed child's Linear state out of In Re…
isadeks Jul 8, 2026
c14cba6
fix(agent): pre-agent build/lint baseline uses the 30min verify ceili…
isadeks Jul 8, 2026
7cb4a87
fix(agent): ensure claude-code native binary is placed at image build…
isadeks Jul 9, 2026
f012732
fix(#247): classify the claude Exec-format/broken-shim failure with r…
isadeks Jul 9, 2026
a6eeb8e
fix(#247): settle a build-failed child's ✅ reaction to ❌, not just it…
isadeks Jul 9, 2026
8035b71
fix(#247): ENOSPC/OOM build kills are infra faults, not build failure…
isadeks Jul 9, 2026
4c6ddde
chore: default agent model -> Opus 4.8 + max_turns 100->200 (port of …
isadeks Jul 9, 2026
f1ee965
fix(agent): explain WHY a task hit max_turns + catch loop-of-variatio…
isadeks Jul 9, 2026
545d32a
fix(#247): don't over-claim on a max_turns spin — offer BOTH remedies…
isadeks Jul 9, 2026
67d84db
fix(agent): log stdout on run_cmd failure so build-gate failures are …
isadeks Jul 9, 2026
4e1ea54
fix(agent): pre-agent baseline OOM-kill (exit 137) is infra, not 'alr…
isadeks Jul 9, 2026
cf34086
fix(cdk): raise BUILD task memory 64→120 GB (max Fargate) — ABCA-662 …
isadeks Jul 9, 2026
8a311a8
fix(agent): route an env-prefixed verify command (VAR=val cmd) throug…
isadeks Jul 9, 2026
19e394c
fix(cdk): cap jest maxWorkers 50%→25% — decouple build peak RAM from …
isadeks Jul 9, 2026
123a3af
style(agent): ruff one-line the needs_shell expr (self-mutation guard)
isadeks Jul 9, 2026
9e27e3a
fix(agent): mise-trust NESTED config roots, not just the repo root (A…
isadeks Jul 9, 2026
3fe99c9
fix(agent): surface the FAILING line from a parallel build DAG, not j…
isadeks Jul 9, 2026
510c7fb
style(agent): ruff quote-normalize in _FAILURE_LINE_MARKERS (self-mut…
isadeks Jul 9, 2026
3fbc6fb
fix(agent): stream build/lint verify output live → full log reaches C…
isadeks Jul 9, 2026
79e35ec
style(agent): ruff one-line streaming test calls (self-mutation guard)
isadeks Jul 9, 2026
7a2bde9
fix(cdk): make ecs-strategy top-of-file import hermetic vs ambient env
isadeks Jul 9, 2026
3fc9060
fix(cdk): grant ec2:DescribeAvailabilityZones to ECS agent task role …
isadeks Jul 9, 2026
5ea9670
fix(build): decouple cdk-test jest workers from cores + add pytest pe…
isadeks Jul 10, 2026
803c44b
fix(agent): pytest-timeout method thread→signal so a hung test is act…
isadeks Jul 10, 2026
7ff91bf
fix(agent): bound the aws_session concurrency test's Barrier + joins …
isadeks Jul 10, 2026
87c2ecf
perf(cdk): raise ECS jest workers 2→3 for the build gate (cdk:test is…
isadeks Jul 10, 2026
68b89e4
perf(cdk): ECS jest workers 3→4 (measured — cdk:test peaks ~2.2 GB, n…
isadeks Jul 10, 2026
1e607aa
fix(cdk): skip the redundant pre-push TEST hook in the agent containe…
isadeks Jul 10, 2026
5df1351
fix(agent): faulthandler watchdog + session-cache reset to kill the E…
isadeks Jul 10, 2026
309ce25
fix(cdk): grant the ECS task role AgentCore Memory write (F-2 ECS-par…
isadeks Jul 10, 2026
e2ee19c
fix: post-agent build OOM — prevent (serialize) + classify (137=infra…
isadeks Jul 11, 2026
220131e
fix(errors): max_turns stays "Exceeded max turns" — observe the repea…
isadeks Jul 14, 2026
3e2d9c7
Merge remote-tracking branch 'upstream/main' into linear-vercel
isadeks Jul 14, 2026
a746a9d
ci: add automated PR review gate workflow (#42)
isadeks Jul 14, 2026
4466a02
docs: add automated PR review gate setup guide (#43)
isadeks Jul 14, 2026
8e31ac1
fix(agent): kill ECS baseline-build hang + early Linear ACK (ABCA-707)
isadeks Jul 15, 2026
a85ec68
fix(linear): start new work from a follow-up comment on a PR-less tas…
isadeks Jul 15, 2026
a9efaa6
Merge remote-tracking branch 'upstream/main' into chore/merge-main-in…
isadeks Jul 15, 2026
6dfb1e4
fix(ecs): drop over-privileged artifacts grant from ECS task role (mi…
isadeks Jul 15, 2026
80d3b02
fix(review-gate): sanitize Idempotency-Key to API-allowed charset
isadeks Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
364 changes: 364 additions & 0 deletions .github/workflows/review-gate.yml

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions .github/zizmor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,19 @@ rules:
# Approve-only job: never checks out or runs PR code, only calls the
# review API; gated on the 'auto-approve' label.
- auto-approve.yml
# Comments-only PR gate: never checks out or runs PR code (pure gh
# api/curl); workflow_run is required for the trusted base-repo context
# so secrets/PAT are available for fork PRs. Untrusted event fields flow
# through env only.
- review-gate.yml
# These secrets are intentionally repo-level, not environment-scoped:
# CODECOV_TOKEN is an upload-only token; AUTOMATION_GITHUB_TOKEN is the PAT
# the upgrade-main PR job needs so its PRs trigger the build workflow.
secrets-outside-env:
ignore:
- build.yml
- upgrade-main.yml
# ABCA_WEBHOOK_SECRET + AUTOMATION_GITHUB_TOKEN are intentionally repo-level:
# the gate has no environment/approval boundary (it only reads state, posts
# comments, and fires the review webhook).
- review-gate.yml
10 changes: 5 additions & 5 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ description = "Test fixture signing secret in Slack verification unit test (not
stopwords = ["test-signing-secret-abc123"]

[[allowlists]]
# Test idempotency-key fixture in orchestration-release.test.ts (not a real
# credential). Suppressed by stopword rather than a .gitleaksignore commit-SHA
# fingerprint: the finding lives in history and SHA fingerprints break whenever
# history is rewritten (rebases / dep-bump merges), which is exactly how #530's
# baseline regressed. A stopword is SHA-independent. See #537 (regression of #530).
# Test idempotency-key fixture in orchestration tests (not a real credential).
# Suppressed by stopword rather than a .gitleaksignore commit-SHA fingerprint:
# the finding lives in history and SHA fingerprints break whenever history is
# rewritten (rebases / dep-bump merges), which is exactly how #530's baseline
# regressed. A stopword is SHA-independent. See #537 (regression of #530).
description = "Test idempotency-key fixture 'orch_abc_SUB-1' (not a real credential)."
stopwords = ["orch_abc_SUB-1"]

Expand Down
20 changes: 19 additions & 1 deletion agent/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*

# Enable Corepack so ``yarn`` / ``pnpm`` resolve out of the box. Many target
# repos (including ABCA itself) drive installs with ``yarn install`` via their
# build command; without this, ``yarn`` is "command not found" (exit 127) and
# the build-verification GATE runs inert — a green build is reported for a repo
# we never actually built (live-caught 2026-06-29 dogfooding ABCA-on-ABCA: the
# agent had to hand-build a ``~/bin/yarn`` shim every run). Corepack ships with
# Node 24; ``enable`` installs the yarn/pnpm shims onto PATH.
RUN corepack enable && corepack prepare yarn@stable --activate 2>/dev/null || corepack enable

# Install Claude Code CLI (the Python SDK requires this binary)
# Then update known vulnerable transitive packages where fixed versions exist.
# Pinned 2.1.191 to match the CLI bundled by claude-agent-sdk 0.2.110 (see
Expand All @@ -52,10 +61,19 @@ RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && \
# returned creds are cached until 5 min before the JSON's `Expiration`, so an
# 8 h task re-assumes the 1 h-capped SessionRole before expiry. Older builds
# only refreshed hourly on a timer, racing the role-chaining cap.
# claude-code@2.1.x ships an error-shim at bin/claude.exe that its postinstall
# (install.cjs) replaces with the platform-native ELF binary. That postinstall
# can silently fall back (leaving the shim in place) — the shim then dies at
# runtime with "Exec format error: 'claude'" even though the native binary is
# present as an optional dep, just never wired up. Re-run install.cjs explicitly
# after the install so the native binary is placed at build time, and hard-verify
# it exec's (``claude --version`` fails the build if the shim is still on PATH).
RUN npm install -g npm@latest && \
npm install -g @anthropic-ai/claude-code@2.1.191 && \
CLAUDE_NPM_ROOT="$(npm root -g)/@anthropic-ai/claude-code" && \
npm --prefix "${CLAUDE_NPM_ROOT}" update tar minimatch glob cross-spawn picomatch
npm --prefix "${CLAUDE_NPM_ROOT}" update tar minimatch glob cross-spawn picomatch && \
node "${CLAUDE_NPM_ROOT}/install.cjs" && \
claude --version

# Install uv (fast Python package manager) — pinned for reproducibility
COPY --from=ghcr.io/astral-sh/uv:0.11.14 /uv /usr/local/bin/uv
Expand Down
34 changes: 34 additions & 0 deletions agent/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ dev = [
"pytest",
"pygments==2.20.0",
"pytest-cov==7.1.0",
"pytest-timeout==2.4.0", # per-test wall-clock cap: a single hung test (network/subprocess/Bedrock without its own timeout) must fail LOUDLY with a traceback, not silently burn the whole build-verify budget (ABCA-684/686: one hang stalled the baseline build past its 3600s ceiling)
"vulture==2.16", # dead-code detection (#282): unused functions/classes ruff F can't see
]

Expand Down Expand Up @@ -130,6 +131,39 @@ ignore = [
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
# Non-TTY output ergonomics. In a captured/piped context (the ECS build gate, CI,
# an agent's Bash tool) pytest's default is a wall of featureless progress dots
# with the "N passed" summary easy to lose in a tail — live-caught on ABCA-691,
# where an agent burned ~6 turns re-running the full suite with different flags
# because it couldn't confirm the result from the dots. ``count`` renders progress
# as an explicit "N/M passed" so a captured log always shows how far it got and how
# many passed; ``-ra`` appends a short summary of every non-passing outcome (with
# reasons) at the end. Both are display-only — they never change test results.
addopts = "-ra"
console_output_style = "count"
# pytest-timeout: hard wall-clock cap PER TEST. A unit test that blocks (an
# unmocked network/subprocess/Bedrock call with no timeout of its own) otherwise
# hangs the whole `mise run build` until the 3600s build-verify ceiling kills it,
# turning one flaky test into an un-diagnosable 60-min stall (ABCA-684/686). With
# this, the offending test fails with a dumped stack in 120s and the suite moves on.
# method="signal" (SIGALRM) actually ABORTS the hung test — pytest runs
# single-threaded in the main thread here, so the alarm interrupts even a blocked
# C-level/socket call. method="thread" only PRINTS the stack and cannot interrupt a
# syscall-blocked test (proven live on ABCA-688: the thread method dumped the stack
# but the build kept hanging ~55 min until the 3600s ceiling). signal is the real fix.
timeout = 120
timeout_method = "signal"
# faulthandler backstop for hangs signal-timeout CANNOT interrupt. SIGALRM only
# fires in the MAIN thread during a test's call phase, so a hang in a WORKER
# thread (a deadlocked Barrier/join), a fixture, or a C-level socket read the
# main thread never returns from is invisible to it — exactly the ECS-only stall
# chased across ABCA-684/686/688 and again on the warm-cache run (53 min of
# silence, signal never fired). This arms faulthandler's dedicated C watchdog
# thread (immune to the GIL and blocked syscalls) to dump EVERY thread's Python
# stack after 300s in a test, so the next hang self-reports the exact file:line
# instead of stalling blind to the 3600s build ceiling. A session-level
# hard-exit watchdog for hangs OUTSIDE any test lives in tests/conftest.py.
faulthandler_timeout = 300

[tool.coverage.run]
branch = true
Expand Down
74 changes: 74 additions & 0 deletions agent/src/clarification_tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""In-process ``request_clarification`` SDK tool (clarify-before-spend, UX #4).

The customer-caught problem: a vague request like "make it faster" was answered
by GUESSING (shipping a plausible PR and charging for it) instead of asking what
was meant. The fix asks the agent to STOP and pose a question when a request is
too underspecified to implement without guessing.

An earlier cut used a text sentinel the agent had to reproduce verbatim on its
final line. That proved unreliable live — the model either shipped a guess or
finished silently without emitting the exact string. A **tool call** is a
discrete, deterministic event: the model either invokes ``request_clarification``
or it doesn't, and the runner sees the ``ToolUseBlock`` in the message stream (no
string-matching, no reproduction). This module defines that tool as an in-process
SDK MCP server; the runner registers it and captures the question, and the
pipeline treats a captured question as a hold-and-ask (no build, no PR).

Kept tiny and side-effect-free: the tool just acknowledges the call. The
authoritative signal is the runner observing the call + its ``question`` arg.
"""

from __future__ import annotations

from typing import Any

#: The in-process MCP server name. The SDK exposes each tool as
#: ``mcp__<server>__<tool>``, so the fully-qualified tool name the runner matches
#: on is :data:`CLARIFICATION_TOOL_NAME`.
CLARIFICATION_SERVER_NAME = "abca"
CLARIFICATION_TOOL_NAME = f"mcp__{CLARIFICATION_SERVER_NAME}__request_clarification"


def build_clarification_server() -> Any:
"""Build the in-process SDK MCP server exposing ``request_clarification``.

Returns the SDK server config dict for ``ClaudeAgentOptions(mcp_servers=...)``,
or ``None`` if the SDK is unavailable (defensive — the runner then simply
doesn't register it and the marker-based fallback still works).
"""
try:
from claude_agent_sdk import create_sdk_mcp_server, tool
except ImportError: # pragma: no cover - SDK always present in the container
return None

@tool(
"request_clarification",
(
"Ask the requester ONE clarifying question and STOP, instead of guessing, "
"when the task is too underspecified to implement without picking among "
"materially different interpretations (e.g. 'make it faster' with no target "
"or slow path named). Calling this opens NO pull request and charges nothing "
"for a guess — the platform surfaces your question to the requester. Only "
"call it for genuinely ambiguous goal-without-substance requests; a task that "
"names what to change is actionable, so just do it."
),
{"question": str},
)
async def request_clarification(args: dict[str, Any]) -> dict[str, Any]:
question = str(args.get("question", "")).strip()
# The tool's own return is only feedback to the agent; the runner captures
# the question from the ToolUseBlock. Tell the agent to stop here.
return {
"content": [
{
"type": "text",
"text": (
"Clarifying question recorded and will be posted to the requester. "
"Do not make code changes or open a PR — end your turn now."
+ (f" (question: {question})" if question else "")
),
}
]
}

return create_sdk_mcp_server(name=CLARIFICATION_SERVER_NAME, tools=[request_clarification])
32 changes: 27 additions & 5 deletions agent/src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,28 @@
# id whose ``requires_repo`` is false. Used by the load-failure fallback to
# decide repo-optionality without loading the file.
REPO_LESS_DEFAULT_WORKFLOW_ID = "default/agent-v1"
# First-party workflow ids that operate on an existing pull request.
PR_WORKFLOW_IDS = frozenset(("coding/pr-iteration-v1", "coding/pr-review-v1"))
# First-party workflow ids that operate on an existing pull request — they
# check out the existing PR branch instead of creating a fresh one. restack-v1
# (#305 A6) re-merges a changed predecessor into an existing stacked-child PR.
PR_WORKFLOW_IDS = frozenset(("coding/pr-iteration-v1", "coding/pr-review-v1", "coding/restack-v1"))
# Clarify-before-spend (customer UX #4): the exact marker a coding/new-task agent
# puts on the FIRST line of its final message when a request is too ambiguous to
# implement without guessing. Its presence tells the pipeline to hold — post the
# question, open NO PR, and surface it as "needs input" rather than a finished
# task. Kept as an unusual sentinel so it can't collide with ordinary prose.
NEEDS_INPUT_MARKER = "[[ABCA_NEEDS_INPUT]]"
# First-party workflow ids that are writeable (NOT read-only). Used only by the
# load-failure fallback to bias an unrecognised id toward read-only (fail closed
# on the write-deny invariant). pr-review-v1 is intentionally excluded (it is
# read-only); default/agent-v1 is excluded because its conservative posture
# should fail closed too.
_KNOWN_WRITEABLE_WORKFLOW_IDS = frozenset(("coding/new-task-v1", "coding/pr-iteration-v1"))
_KNOWN_WRITEABLE_WORKFLOW_IDS = frozenset(
(
"coding/new-task-v1",
"coding/pr-iteration-v1",
"coding/restack-v1",
)
)


def resolve_github_token() -> str:
Expand Down Expand Up @@ -460,9 +474,13 @@ def build_config(
dry_run: bool = False,
task_id: str = "",
system_prompt_overrides: str = "",
build_command: str = "",
lint_command: str = "",
resolved_workflow: dict | None = None,
branch_name: str = "",
pr_number: str = "",
base_branch: str | None = None,
merge_branches: list[str] | None = None,
channel_source: str = "",
channel_metadata: dict[str, str] | None = None,
trace: bool = False,
Expand All @@ -483,7 +501,7 @@ def build_config(
resolved_github_token = github_token or resolve_github_token()
resolved_aws_region = aws_region or os.environ.get("AWS_REGION", "")
resolved_anthropic_model = anthropic_model or os.environ.get(
"ANTHROPIC_MODEL", "us.anthropic.claude-sonnet-4-6"
"ANTHROPIC_MODEL", "us.anthropic.claude-opus-4-8"
)
# Small/fast auxiliary model (WebFetch summarization etc.). Falls back to the
# deployed ANTHROPIC_DEFAULT_HAIKU_MODEL env, then the platform default. Must
Expand Down Expand Up @@ -573,6 +591,8 @@ def build_config(
max_turns=max_turns,
max_budget_usd=max_budget_usd,
system_prompt_overrides=system_prompt_overrides,
build_command=build_command,
lint_command=lint_command,
resolved_workflow=workflow,
policy_principal=policy_principal,
read_only=workflow_read_only,
Expand All @@ -581,6 +601,8 @@ def build_config(
is_pr_workflow=is_pr_workflow,
branch_name=branch_name,
pr_number=pr_number,
base_branch=base_branch,
merge_branches=merge_branches or [],
task_id=task_id or uuid.uuid4().hex[:12],
channel_source=channel_source,
channel_metadata=channel_metadata or {},
Expand All @@ -603,7 +625,7 @@ def get_config() -> TaskConfig:
issue_number=os.environ.get("ISSUE_NUMBER", ""),
github_token=os.environ.get("GITHUB_TOKEN", ""),
anthropic_model=os.environ.get("ANTHROPIC_MODEL", ""),
max_turns=int(os.environ.get("MAX_TURNS", "100")),
max_turns=int(os.environ.get("MAX_TURNS", "200")),
max_budget_usd=float(os.environ.get("MAX_BUDGET_USD", "0")) or None,
aws_region=os.environ.get("AWS_REGION", ""),
dry_run=os.environ.get("DRY_RUN", "").lower() in ("1", "true", "yes"),
Expand Down
2 changes: 1 addition & 1 deletion agent/src/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
TaskResult,
TokenUsage,
)
from pipeline import main, run_task # noqa: F401
from pipeline import main, run_task, run_task_from_payload # noqa: F401
from post_hooks import ( # noqa: F401
ensure_committed,
ensure_pr,
Expand Down
Loading
Loading