Skip to content

Commit ea45a64

Browse files
ci(bots): add daily retrospective (rolling learning PR) + bump engine
Adds the daily learning-extraction flow (was not enabled on this repo) on the current engine d05dcb1, which maintains ONE rolling learning PR on a stable branch (ai/learning-pr). - engineer-bot-learning.yml: daily cron + workflow_dispatch; PAT-free via the existing bot-prelude; actions:read for Track B (author-run mining). - .bot/config.yaml: add retrospective: block (engine-owned batch prompt, no override) and author.knowledge_log to close the loop (author reads what the retrospective writes). - Seed .claude/knowledge/learning-log.md. - Bump bot-prelude engine-ref default 5368de7 → d05dcb1. Co-authored-by: Isaac Signed-off-by: eric-wang-1990 <e.wang@databricks.com>
1 parent a94cfe2 commit ea45a64

4 files changed

Lines changed: 157 additions & 1 deletion

File tree

.bot/config.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ author:
8686
issue_url: ISSUE_URL
8787
context_files:
8888
- issue_body.txt # {{issue_body}}
89+
# Close the loop: the author phase READS this log (newest-first, capped) into its
90+
# system prompt as accumulated lessons, so retrospective learnings actually steer
91+
# future fixes. MUST match retrospective.log_path below (write half ↔ read half).
92+
knowledge_log: .claude/knowledge/learning-log.md
8993

9094
# Engine orchestration for the author phase. `bug-fix` runs the plan →
9195
# author_tests → fix pipeline (write a failing test → fix the code → re-run to
@@ -94,3 +98,20 @@ author:
9498
# testing specifics (commands, layout, fixtures) live in prompts/engineer/
9599
# system.md, not here.
96100
flow: bug-fix
101+
102+
# Daily-cron learning extraction (retrospective flow). Run by engineer-bot-learning.yml
103+
# via `python -m databricks_bot_engine.engineer_bot.retrospective`: over an adaptive
104+
# look-back window the engine ITSELF gathers merged PRs (diff + review comments) AND
105+
# recent engineer-bot author-run logs, and if the model finds durable learnings opens
106+
# ONE rolling PR appending a dated section to log_path. Human-gated — never commits the
107+
# canonical log directly. Omitting this block makes the retrospective a no-op.
108+
#
109+
# No `system_prompt` override: the engine ships the authoritative batch-aware base
110+
# (engineer_prompts.RETRO_SYSTEM_PROMPT); a `.bot/prompts/` override is optional.
111+
# No `context_files` — the daily-cron engine enumerates its own sources via the
112+
# GitHub API (context_files is an AUTHOR-phase key only).
113+
retrospective:
114+
log_path: .claude/knowledge/learning-log.md # MUST match author.knowledge_log above
115+
branch_prefix: ai/learning-pr- # rolling PR lands on the derived stable branch `ai/learning-pr`
116+
pr_label: engineer-bot-learning
117+
author_workflow: engineer-bot.yml # Track B: which workflow's author runs to mine

.claude/knowledge/learning-log.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Engineer-bot learning log
2+
3+
Durable, reusable engineering learnings distilled by the daily retrospective
4+
(`engineer-bot-learning.yml``databricks_bot_engine.engineer_bot.retrospective`).
5+
Each daily run appends one dated section of 0..N learnings to a single rolling PR
6+
until a human merges it. The engineer author phase reads this log (see
7+
`.bot/config.yaml` `author.knowledge_log`) so past lessons steer future fixes.
8+
9+
## Entries
10+
11+
--- *Add new entries above this line (oldest→newest); newest sections sort to the bottom.* ---

.github/actions/bot-prelude/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ inputs:
3131
# value to move every bot to a new engine commit; never @main.
3232
description: 'Engine commit SHA (full 40-char) to install.'
3333
required: false
34-
default: '5368de773858bef9b2a8bbf3099d08a4132a8487'
34+
default: 'd05dcb113332401b4aee8d6aa05c7107399ad44f'
3535
engine-repo:
3636
description: 'owner/name of the engine repo.'
3737
required: false
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Engineer Bot — learning (retrospective) extraction — DAILY CRON.
2+
#
3+
# Over an adaptive look-back window the engine gathers merged PRs (diff + review
4+
# comments) AND recent engineer-bot author-run console logs ITSELF via the GitHub
5+
# API — no in-workflow context gathering, no per-PR trigger — and if the model
6+
# finds durable, reusable learnings, opens ONE ROLLING PR on a stable branch
7+
# (`ai/learning-pr`), appending a dated section per day until a human merges it.
8+
# Human-gated by design: it NEVER commits the canonical log directly.
9+
#
10+
# Own job (NOT `uses: databricks/databricks-bot-engine/...`): an external repo
11+
# can't resolve the internal engine's reusable workflows ("not found"). It shares
12+
# the SAME prelude the other bots use — ./.github/actions/bot-prelude (tokens +
13+
# Node + pinned engine install) — so the engine pin stays single-sourced in
14+
# bot-prelude's `engine-ref` default (no second SHA to drift).
15+
#
16+
# Opt-in is purely via the `retrospective:` block in .bot/config.yaml + this
17+
# workflow; absent that block the engine phase is a clean no-op.
18+
name: Engineer Bot — Learning
19+
20+
on:
21+
schedule:
22+
# 17:23 UTC daily — off-peak, off-:00 minute (GitHub delays/drops on-the-hour crons).
23+
- cron: "23 17 * * *"
24+
workflow_dispatch:
25+
inputs:
26+
since:
27+
description: 'ISO lower bound to bound (shorten) the window and recover a wedged flow. Empty = adaptive cursor.'
28+
type: string
29+
default: ''
30+
window-hours:
31+
# STRING, not number: a `type: number` workflow_dispatch input fails the
32+
# whole run at startup ("workflow file issue") when combined with the
33+
# `schedule` trigger. argparse coerces it to int downstream.
34+
description: 'Fallback look-back window (hours) used only when there is no prior successful run.'
35+
type: string
36+
default: '24'
37+
38+
permissions:
39+
contents: write # push the learning branch / open the learning PR
40+
pull-requests: write
41+
actions: read # Track B lists engineer-bot author runs + logs via the App token;
42+
# the engineer-bot App installation must ALSO carry actions:read
43+
# (a missing scope surfaces as a 403 that fails the whole run —
44+
# list_author_runs raises, no escape hatch).
45+
id-token: write # JFrog OIDC exchange for the engine/SDK/CLI install
46+
47+
concurrency:
48+
# One learning run at a time; a queued run waits rather than racing the rolling
49+
# PR's branch. Not keyed on a PR number (this is a cron, no PR event).
50+
group: engineer-bot-learning-cron
51+
cancel-in-progress: false
52+
53+
jobs:
54+
learning:
55+
environment: azure-prod # DATABRICKS_HOST / DATABRICKS_TOKEN live here
56+
runs-on:
57+
group: databricks-protected-runner-group
58+
labels: [linux-ubuntu-latest]
59+
timeout-minutes: 20
60+
steps:
61+
# Checkout the default branch (the learning PR is cut from it) FIRST, so the
62+
# local `./` composites below resolve. persist-credentials:false — the
63+
# retrospective sets its own authenticated push remote (see the run step),
64+
# so no token is left in .git/config.
65+
- name: Checkout default branch (learning PR is cut from it)
66+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
67+
with:
68+
fetch-depth: 0
69+
persist-credentials: false
70+
71+
# Route pip through the JFrog proxy for the engine install (the retrospective
72+
# reads diffs via the API; it doesn't build/run the connector, so no poetry
73+
# deps needed — just a Python interpreter + the engine). MUST run before
74+
# bot-prelude (install-bot-engine reuses its PIP_INDEX_URL / JFROG_ACCESS_TOKEN).
75+
- name: Set up JFrog (pip)
76+
uses: ./.github/actions/setup-jfrog
77+
with:
78+
uv: "true"
79+
80+
- name: Setup Python
81+
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
82+
with:
83+
python-version: '3.11'
84+
85+
# Shared prelude: mint the engineer-bot token (opens the learning PR) + the
86+
# engine-scoped token, set up Node, install the pinned engine (PAT-free). The
87+
# engine pin comes from bot-prelude's `engine-ref` default — the SINGLE source
88+
# of truth for every bot; there is no second SHA in this file to drift.
89+
- name: Bot prelude (tokens + Node + engine install)
90+
id: prelude
91+
uses: ./.github/actions/bot-prelude
92+
with:
93+
app-id: ${{ secrets.ENGINEER_BOT_APP_ID }}
94+
private-key: ${{ secrets.ENGINEER_BOT_APP_PRIVATE_KEY }}
95+
96+
# NOTE: no git-identity step — the engine's retrospective configures the git
97+
# user AND DCO sign-off itself from .bot/config.yaml `bot_login_prefix`.
98+
# NOTE: no context-gather step — the daily-cron engine enumerates merged PRs
99+
# + author runs itself over the adaptive window.
100+
- name: Extract learnings + open rolling PR
101+
env:
102+
GH_TOKEN: ${{ steps.prelude.outputs.token }}
103+
GITHUB_REPOSITORY: ${{ github.repository }}
104+
# Only the `<workspace>/serving-endpoints/` prefix matters:
105+
# sdk_agent.translate_endpoint rewrites this to `.../serving-endpoints/anthropic`
106+
# and discards the model path segment. The effective model comes from
107+
# .bot/config.yaml `retrospective.model` (or the engine default).
108+
MODEL_ENDPOINT: https://${{ secrets.DATABRICKS_HOST }}/serving-endpoints/anthropic/invocations
109+
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
110+
RUNNER_TEMP: ${{ runner.temp }}
111+
SINCE: ${{ inputs.since }}
112+
WINDOW_HOURS: ${{ inputs.window-hours }}
113+
# The retrospective pushes the learning branch with a plain `git push
114+
# origin`, and the checkout ran persist-credentials:false — so set an
115+
# authenticated push remote from the minted App token first, mirroring
116+
# engineer-bot.yml's publish step. --since / --window-hours are passed only
117+
# when provided via workflow_dispatch (the schedule trigger leaves them
118+
# empty → the adaptive cursor drives the window).
119+
run: |
120+
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
121+
args=(--repo-dir "$GITHUB_WORKSPACE")
122+
[ -n "$SINCE" ] && args+=(--since "$SINCE")
123+
[ -n "$WINDOW_HOURS" ] && args+=(--window-hours "$WINDOW_HOURS")
124+
python -m databricks_bot_engine.engineer_bot.retrospective "${args[@]}"

0 commit comments

Comments
 (0)