Pedroro/release scout - #457
Draft
pedro romero vargas (p3dr0rv) wants to merge 161 commits into
Draft
Conversation
… projects - Introduced `checks.py` in the `release-agent/tools` directory, implementing various readiness checks including Azure DevOps build definition access, HTTP reachability, and pipeline variable management. - Updated `settings.gradle` to comment out several project inclusions, including `AcaPlugin`, `LinuxBroker`, `java-linux-test-app`, `LinuxBrokerPackage`, and `NativeAuthSample`, to streamline the build configuration.
…e conditions and ensure safe parallel execution; enhance error messaging for Azure DevOps authentication issues.
|
❌ Work item link check failed. Description does not contain AB#{ID}. Click here to Learn more. |
Engine (gate integrity): - sign: remove blanket --all; CLI now requires explicit --item ids + refuses a bare sign, and records each attestation individually with an evidence --note. Closes the hole where sign --all attested every human item in one blind call (a release reached Phase 0 without real confirmation). - readiness.sign() carries a per-item evidence note. Readiness config/UX: - silent_perms.required_servers now includes kusto + icm (the MCP servers the adx_access / oncall_now checks call) so they don't prompt on first run. Skill (A: dedupe, B: modular split): - Split the 48KB monolith SKILL.md into a lean 7KB core (golden rules + behaviour dispatch + reference routing table) plus skill/reference/*.md read on demand (readiness-gate, starting-and-scheduling, presenting-status, commands, phases/preflight, phases/_TEMPLATE). Core is now well under Scout's inline limit, so it no longer spills / gets skimmed. - Fix regression where the readiness table was suppressed: render the checklist table FIRST, then handle silent-runs (was "before showing the checklist"). - Anti-assumption rule: never attest/approve on an echoed m_ask_user result. - Scale convention: add a phase = phases.yaml + phases/agents/<id>.py + reference/phases/<id>.md + one routing-table row. bootstrap.ps1: auto-install Python via winget + silent pyyaml; verify Scout present + skill copy; restart Scout by default (guarded when run inside a Scout session); UTF-8 + detached-launch fixes; clearer folder/run instructions. Tests: 101/101 (added regressions for bare-sign refusal, no --all, evidence note). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Recurring regression: the model ran checklist (which auto-logs) but did not paste the table into its reply, then asked for attestations in a table-less message — losing the context the user needs. - Core golden rule #2: running a command != showing it; the user only sees what you paste. - New golden rule #2b: NEVER ask for a gate decision or attestation in a message that doesn't contain the freshly-rendered table (in the SAME message). - readiness-gate.md step 3b: paste the table verbatim into the same message as the attestation question. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ecks Two UX nits from testing: 1. Table rendered twice (once mid-auto-checks, once after). Restructured the readiness flow to render the checklist table ONCE, in step 3b, right before the attestations — steps 1-3a are now quiet setup (verify + silent-runs + scout checks) with no half-done table. Step 1 uses �erify (terse pass/fail) instead of checklist --verify (big table). 2. Model asked the user permission to run the ADX/Kusto query even though the kusto MCP server is auto-approved (verified: the query runs silently). The prompt was the model asking, not Scout. Step 3a now explicitly forbids asking permission to run the scout-assisted auto checks — they're auto-approved and must run silently. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… auto checks" This reverts commit b8cc7b7.
…uctural fix) Prompt-level 'render the table then ask' instructions were fragile — the model would run checklist (auto-logged) but not paste it, then ask attestations in a table-less message. Fix structurally in the engine instead: - render.readiness_table now appends a '✋ Your confirmation needed' section listing the outstanding attest items, but ONLY once every auto item is satisfied. The table and the attestation prompt are now a single deterministic output — you can't show one without the other, and the prompt can't appear before the auto checks are done. Engine controls the ordering, not the model. Skill readiness flow simplified to match: run all auto checks silently first (never ask permission to run the ADX/on-call MCP calls — they're auto-approved), then render checklist ONCE (its output carries the confirmation section) and fire m_ask_user in the same message. Fixes both nits: single table render, and no spurious 'can I run the query?' prompt. Tests: 102/102 (added test_attest_prompt_welded_only_after_auto_done). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…put (structural fix)" This reverts commit c8c0e13.
…plays) Root-cause of the recurring 'no table, just a list' regression: it's controlled by WHERE the checklist render sits in the tool-call sequence, not by wording. - A checklist table render that is the model's FIRST action is pasted verbatim. - A render placed AFTER a chain of silent tool calls (verify/record-check/ m_get_settings) gets summarized into a plain list (model switches to wrap-up mode). The first render also primes verbatim-pasting for the second. So the double-render is the control mechanism, not waste. Codified as a DESIGN INVARIANT in readiness-gate.md so future edits don't collapse to a single end-of-flow render and reintroduce the regression. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…wo-render flow) Now that we understand the render-first mechanism, re-apply the engine welded prompt WITHOUT the flow reorder that broke display: - render.readiness_table appends '✋ Your confirmation needed' only once all auto items are satisfied. In the working two-render flow this means render #1 (checklist --verify, scout items still pending) stays a clean table with NO prompt, and render #2 (after the silent scout checks) carries the welded attestation list. Verified: render1 no prompt, render2 has prompt. - Keeps the proven display-first two-render flow (render #1 primes verbatim paste); adds deterministic attestation context to render #2 from the CLI so the model doesn't hand-build the list. - step 3b notes the confirmation section comes from the CLI. Tests: 102/102. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lock User wants the table shown once, not twice. The two outputs are inherent (one before the silent auto-checks, one after) — the fix is to make the SECOND output a compact confirmation block, not the full table again. - render.py: full table no longer carries the welded prompt; new public render.attest_prompt(chk) returns just the '✋ Your confirmation needed' block (or a status line if auto checks aren't done / gate cleared). - new CLI mode: checklist --attest-prompt emits ONLY that block (no table). - Flow: render #1 = full table (display-first, primes verbatim paste); silent auto checks; render #2 = checklist --attest-prompt = block only. One table total. Verified E2E: render1 has table/no block, render2 has block/no table. - Invariant doc + step 3b updated to the single-table design. Tests: 102/102. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mplete table once + deterministic attestation card
Fixes the recurring readiness-display problems with a two-part approach:
1. Deterministic attestation card (removes the LLM from the critical path).
- render.attest_prompt_payload(chk, release) builds the exact m_ask_user
payload the engine owns: question + answer cards (1 confirm_all + one
decline per outstanding attest item) + confirm_items + recommendedIndex.
ready:false until all auto checks pass. On-call window dates surfaced in
the confirm_all description.
- `checklist --attest-prompt --json` returns that payload; the skill passes
it straight to m_ask_user. The always-rendered Scout card is the guaranteed
source of truth even if the markdown table doesn't render.
2. Table shown ONCE, AFTER full evaluation (the requested UX).
- Skill flow reordered: steps 1-3 run all auto checks SILENTLY (Python
verifiers, silent_perms, on-call, ADX) with no table/partial renders; step
4 renders the complete checklist table (all [auto] items resolved to the
final state) with explicit "paste verbatim, do not summarize" framing;
step 5 presents the deterministic card; steps 6-8 map the answer to
sign/decline. No more early/incomplete table, no spurious ADX permission
prompt.
Gate integrity preserved throughout: no --all, explicit per-item sign, never
attest on assumption.
Tests: 103/103 (added test_attest_prompt_payload_is_deterministic_card,
test_attest_prompt_is_separate_render_never_in_table).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The phase map and current-phase steps tables used an empty-header first column just for the status icon (| | # | Phase | Done |). Scout's table renderer gives that empty column a huge width, leaving a big gap before the # column. Fix: drop the standalone icon column and prefix the icon onto the Phase/Step name — '| 0 | 🗓 Pre-flight … |' instead of '| 🗓 | 0 | Pre-flight … |'. Clean 3-/2-column tables, no empty gap. (Readiness table left as-is — user-validated.) Tests: 103/103. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Give every Phase-0 step ONE home under steps/<phase>/ authoring a single
build(state) -> Outcome, replacing the split where scout steps were scattered
across phases.yaml + stub_runner + commands/*.py + templates + skill md.
Outcomes (orchestrator/outcomes.py): Done | Blocked | NeedsHuman | NeedsSkill.
Generic dispatcher `step-action` serializes a migrated step's outcome as JSON so
the skill reacts uniformly (needs_skill -> run tool + record-step; needs_human ->
show prompt + done). Agent steps run in-process during `next` (step-action
refuses them).
Migrated (steps/preflight/):
scout : notice, flight_reminder, lockdown (gather-then-decide via check-lockdown)
attest: confirm_reminders, vitals (NeedsHuman prompts)
agent : breaking, cg, cron, wiki (Done/Blocked, engine-run)
Shared libs: steps/lib/{context,templating,agent}. Legacy homes
(phases/agents/preflight.py, commands/notice.py, commands/lockdown.py) reduced to
thin compatibility/recorder shims so the engine + 103 tests are unchanged.
Also fixes:
- render.py: phase-map legend was glued into the table as a one-column row
(missing blank line) -> now a separate italic caption.
- skill docs: render the status table ONCE per advance pass (after the work),
not an interim table before running the scout steps.
103/103 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ils + knowledge
Replace the dry-run boolean with a real-by-default model plus a personal,
gitignored mocks.local.yaml overlay for safe testing:
- Remove dry_run entirely (state/engine/render/cli/steps). Every run makes real
calls; the fake "[dry-run] Would…" branches are gone.
- Mock overlay (orchestrator/mocks.py + steps/lib/mockctx.py): mocks.local.yaml
can, per step, force outcome (done|blocked), redirect a real send (send_to),
or inject inputs so the step's REAL logic runs on your data (cg alerts,
breaking changelog, cron run, wiki page_name/name_suffix, notice variant).
Readiness entry-gate auto checks are mockable too (readiness.<item>).
- Each step DECLARES its mockable knobs (MOCKABLE); `mock-spec` lists exactly
what every step exposes (steps + readiness), with typo detection.
Status "Details" column (render): a third column captures each step's execution
outcome from its stored note — where a lockdown clashed, the breaking change, CG
alerts found, the created wiki link — generic for all current/future steps, with
rich multi-line notes expanding below. Durable refs are now first-class:
StepState.links [{name,url}] (wiki page, CG alerts page + per-alert deep links),
threaded Done/Blocked -> StepResult -> StepState -> render.
Step knowledge base (config/knowledge.yaml + orchestrator/knowledge.py +
`step-info`): curated per-step help (what/where/how/links/faqs) so the skill
answers step questions accurately instead of guessing. Fixes the Play Console
vitals navigation. SKILL.md consults step-info for step questions.
Also: readiness table groups auto items before attest (oncall_now before
play_console_access); breaking-change entries no longer double their bullet.
106/106 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…registries Make a step a single self-contained module so adding one touches ~2 files and can never silently drift: - Auto-discover step modules: steps/__init__.discover() scans steps/<phase>/*.py. Remove the hand-maintained _STEPS list. - Engine resolves agent steps via steps.get_step() (module.run when KIND==agent), stub fallback otherwise. DELETE phases/agents/ (package + REGISTRY) and the dead `agent:` field from config/phases.yaml — no runner registry, no agent-id indirection. - Co-locate step CONFIG into each module (CONFIG constant); remove config/preflight.yaml and orchestrator/phase_config.py. The module is now the single home for a step's logic + mock knobs + config. - Structural guardrail test: every discovered module maps to a phases.yaml step and its KIND matches the config flags — drift fails LOUDLY. config/phases.yaml is now pure COMPOSITION (which steps, order, deps, flags); a step's logic/config lives in its module; knowledge stays in config/knowledge.yaml (a module may override via KNOWLEDGE). README documents the 2-file "adding a step" contract. Tests point at steps.preflight.* directly; block-path tests use the mock overlay instead of registry patching. 107/107 tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Correct the Component Governance alerts link to the real One/AD-MFA phonefactor-phoneApp-android componentGovernance page (in the cg module CONFIG and knowledge.yaml). - Pending scout steps (e.g. lockdown) now render as 'Scout runs this' instead of 'Your action' and are no longer flagged as needing the user; they only escalate to a blocked user action when a scout step records an attention/overlap. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The knowledge base had no ownership fact for the CG step, so 'who fixes this?' was answered by guessing (wrongly deferring to the component owner). Record the real rule: the RELEASE OWNER remediates Component Governance alerts, including authoring and landing the fix PR. Add a 'who' field to the knowledge schema/renderer and populate it (plus a matching FAQ) for preflight.cg. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Free-form step questions (what/why/who/how about a step) are exactly the 'interaction' the event log is meant to capture, but nothing journaled them, so surfacing missing/inaccurate knowledge (e.g. CG ownership) left no trace. Add a thin two-sided 'step_qa' event: EventLog.qa(), a 'journal --kind qa --question ... --answer ...' path, log-viewer rendering, and a questions_answered rollup in summarize(). Wire the skill so that, during an active release, answering a step question from step-info silently journals the pair (skipped when no release run exists). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ocalization Build out the first three CCD steps as self-contained scout modules under steps/ccd/ (auto-discovered), each doing the real work idempotently: - final_reminder (email) — CCD-day 'code complete is TODAY' notice to the Android DL (the 'update' variant of the Phase-0 notice template). - pr_reminder (Teams) — NEW step; posts to the 'Code reviews' chat: merge every required PR before the 11 PM auto branch-cut; a CCD delay or post-CCD cherry-pick both need Moumita Ghosh's (moghosh@) approval; merge string PRs before the noon localization run. - localization (trigger)— fires pipeline 405133 (msazure/One) with isCreatePrSelected=true; PR created => strings to merge, no PR => none. Each module carries CONFIG (incl. fire_at_local timing), MOCKABLE knobs, knowledge.yaml entries, and tests. phases.yaml marks the three source: scout and inserts pr_reminder (P1-1b); branch_cut stays the human gate. Timing is encoded per-step (09:00 / 12:00) for a per-release CCD automation to drive; the engine stays date-based. EXTERNAL-REFERENCES catalogs the new chat, pipeline, and approver. Test harness gains _clear_ccd_scout so flow tests reach the branch_cut gate. 114/114. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wire the timed Phase-1 automations into release-start provisioning, and close the traceability gap: the registry knew an automation's id/release/purpose but not WHICH STEPS it drives. - config/automations.yaml: declarative source of truth mapping each per-release automation to the steps it drives. Timing is DERIVED from each step module's fire_at_local (no duplication). - orchestrator/automations.py: plan(release, ccd) emits concrete specs (name/schedule/steps/prompt/registration) for the skill to create; validate() enforces every fire_at_local step is owned by exactly one automation and each automation's steps exist + share one fire time. - registry: entries now carry steps[]; list(step=...) is the reverse lookup (which automation owns a step). �utomation plan CLI action + --step / --step-filter flags. - Guardrail test test_automations_cover_every_scheduled_step makes the mapping self-enforcing; plus registry-linkage and plan tests. - SKILL/commands/scheduling docs: provision timed automations at start (register WITH --step), reverse/forward lookup, runtime journaling. 117/117. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
'Release push reminders' drives no steps — it advances the whole release via hourly tick. An empty steps[] read the same as 'not filled in', so label the category explicitly. Registry entries now carry a 'kind': step-driving (owns steps) or release-level (whole-release, no steps), auto-derived from whether steps are present, with a guard that the two can't contradict. kind_of() derives it for legacy entries. CLI: --kind on register (override) and list (filter); list shows [kind] and '(release-level - no steps)'. Docs note push reminders is release-level. 118/118. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Code Complete Day is now three scout steps (final_reminder, pr_reminder, localization) with NO gate: - branch_cut: removed — the release branch is cut AUTOMATICALLY at 11 PM, there is no manual cut action, so a human 'cut the branch' gate was wrong. - precheck_prs: removed — there's no reliable signal for which PRs are 'required' for a release, so an automated pre-check can't be built honestly. - verify_trigger: removed from Phase 1 — verifying the overnight/auto build fits Phase 2 (Build & Lib Verification), not Code Complete Day. Consequence: the first human gate is now go_test (Phase 2). Updated the flow tests (first gate go_test, second stop the bug-bash ui_failures hold), the phase-shape test, the mocks example, and stale comments. 118/118. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make localization a small state machine instead of fire-and-describe:
- TRIGGER: build() runs pipeline 405133 (isCreatePrSelected=true); the runner
calls record-localization-run to store the build id + start time and leaves
the step IN-FLIGHT (StepState gains a durable data dict).
- POLL: a per-release "every 10 minutes" poller automation calls
check-localization; the pure decide() applies:
* running and under 3h -> wait, poll again
* running and over 3h -> email the release engineer (with the manual-steps
localization doc) and hold the step
* complete -> parse the OneLocBuild@3 log for the
"Pull request created with ID" line; if found, post that PR to the Code
reviews chat for review and mark done (with the PR link); else done (no
strings).
All decision logic is pure/tested; IO is done via NeedsSkill/decision payloads.
Adds: steps/ccd/localization.py rewrite (helpers, decide, KNOWLEDGE incl. the
eng.ms localization doc), orchestrator/commands/localization.py
(record-localization-run, check-localization), StepState.data, an interval
"every N" automation kind in automations.yaml + planner/validate (pollers are
exempt from fire_at_local single-owner accounting; may share a step with a
time-of-day trigger), and docs/refs. 124/124.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ocument orgs Real-tenant check against build 176407869 (msazure/One) confirmed the ADO MCP can't reach that org (TF200016) but az can. So: - localization CONFIG carries the exact az reads (az_read: status via `az pipelines build show`; OneLocBuild@3 log id via `az devops invoke ... timeline`; log content via `... logs`). build()._trigger and the poller automation prompt now spell these out for msazure/One. - extract_pr() prefers the full PR URL the OneLocBuild@3 log prints after the id (real form includes /DefaultCollection/), falling back to the template; pr_url_template updated to the DefaultCollection form. - KNOWLEDGE explains MCP-can't-reach-msazure and the az read path. Also document the two-org reality in EXTERNAL-REFERENCES: Engineering lives in identitydivision (ADO MCP bound here); One lives in msazure.visualstudio.com (az only). 125/125. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ore EOD) When the completed localization run's PR is posted to the Code reviews chat, the message now @mentions the release engineer (release owner) and asks them to ensure the PR is merged before EOD. _review_post builds the Teams mention: an <at id="0"> tag in the html content matched by a mentions[] entry (id=owner UPN, userIdentityType=aadUser) that workiq_send_chat_message consumes. Falls back to a plain (unmentioned) post when no owner email is set. Tests + KNOWLEDGE updated. 126/126. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two per-step mock knobs (exercised in a real msazure/One test run, build
177042471):
- create_pr (input): overrides isCreatePrSelected on the trigger; set false to
run the pipeline WITHOUT creating a PR.
- send_to (post): redirects the completion PR post to your own chat ('me').
Applied by check-localization, since the post happens in the poll decider,
not build().
step_action's payload-override now only touches kind:payload knobs, leaving
input (build) and post (poller) knobs to their proper stages. 126/126.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 1343-line, 66 KB tools/pipelines.py is split into tools/pipelines/ (6 files,
largest 18 KB) by concern:
- _rest.py — az/ADO REST primitives
- orchestrator.py — Orchestrator/Checker/MRWP run discovery, stages, timeline,
approvals + the Engineering release-chain coordinate constants
(moved here from the report layer, their proper owner)
- tests_results.py — test classification, retry reconciliation, summaries, verdicts
- rc_model.py — release_report/assemble_rc_model + version formatting
- auth_app.py — Authenticator (msazure/One) build+UI discovery, tagging, PRs
- __init__.py — façade: re-exports every public + underscore name in dep order
Public API is byte-identical (`tools.pipelines.<anything>` unchanged), so all ~40
consumers are untouched. Intra-package calls go through the package namespace
(`_pp.foo()`) so the ~31 test monkeypatch sites keep working with zero test edits.
349 tests pass; verified with a live ADO read through the package.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 7068-line tests/test_engine.py is split into a shared tests/_harness.py (all 34 helper functions + _SAFE_AGENTS + constants, auto-exporting its whole namespace) and 12 per-area test files (test_core, test_finalize, test_build_verify, test_readiness, test_bug_bash, test_preflight, test_automation, test_ccd, test_schedule_state, test_sim, test_tools, test_status_email). Every test body is byte-identical — blocks were sliced verbatim and re-homed; each file reproduces the original module scope via `from tests._harness import *`. Collection = 349, run = 349 passed (exact match with the original). The existing conftest.py (path + autouse network guard) works unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Scout/agent steps return NeedsSkill(tool, payload={followup_command}); those
engine-command names live as string literals in step code and prose in SKILL.md,
so they can silently drift from the registered CLI commands on a rename.
- orchestrator/outcomes.command_verb(): codifies the contract seam — extracts the
engine-CLI verb from a followup_command / engine-command tool, returns None for
MCP tools (workiq_*/microsoft_teams-*/kusto_query/azure_devops-*).
- tests/test_contract.py: asserts every followup_command and every engine-command
NeedsSkill tool names a REGISTERED CLI command (scans steps/ + orchestrator/),
plus a non-vacuous sanity check. Rename a command without updating the string
-> fails loudly.
353 tests pass (349 + 4).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Automation naming: every provisioned automation now uses one standard title format `<release-id> · <scope> — <label>` (release first, then the phase display name, then the short purpose) so titles are consistent and scannable. Adds automation_name() + phase_label() helpers in orchestrator/automations.py; config/automations.yaml entries switched from a verbose templated `name:` to a short `label:` (scope derived from the phase, with an optional `scope:` override for non-phase automations). Skill docs, knowledge, and the finalize step reference the new names. Phase-table fix: in status_views._current_steps, an unopened phase now shows EVERY not-yet-run step uniformly as "Not open yet" — the not_phase_due check moved above the gate/scout/auto checks so scout steps no longer mislabel as "Scout runs this — automatic" while their agent/human peers show "Not open yet" (the confusing mix). Tests: +4 (name-format + helpers; unopened-phase uniform vs open-phase differentiated). 357 pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The push-reminder loop's prompt runs `next --json` to advance the release and read `scout_pending`, but the `next` subparser never defined --json — so it errored and Scout fell back to `next` then `status --json`. `next` now accepts --json and, after advancing, prints status_report() (same shape as `status --json`, carrying scout_pending), matching the docs and collapsing the two-call dance into one. Test: next --json emits valid JSON with scout_pending; plain next still prints the human advance block. 358 pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Jia Le He is leaving the project. Removed from both roles: - notice/reminder email recipients (preflight.notice, ccd.final_reminder) + the knowledge/EXTERNAL-REFERENCES mentions of that DL - bug-bash always_excluded list (distribution.yaml) + the two knowledge prose mentions The eligible-testers test swaps her for a neutral `excluded@x` placeholder so exclusion-removal coverage is preserved. 358 pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The skill assumed the android-complete clone lived at C:\repos — wrong for
other users. The engine was already portable (cli_common self-locates from
__file__); the gap was the skill docs' hardcoded paths.
- New engine command `paths [--json]` reports the self-located roots
{agent_root, repo_root, runs_root} — the source of truth for where to cd.
- SKILL.md gains a FIRST RUN block (runs once per machine, before Discover):
recall a remembered path; else auto-detect the release-agent clone, run
`paths --json` to canonicalize, ALWAYS confirm with the user, then
m_remember it. Introduces <AGENT_ROOT>/<REPO_ROOT> placeholders; "Where
things live", "start a release", and commands.md now use them.
- Headless automation prompts (push reminders, status email) instruct
substituting the absolute confirmed path, since a placeholder can't resolve
with no one watching.
Test: paths reports self-located roots + honors --runs-root; JSON shape. 359 pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The start flow asked two confusing questions: "which month?" (ambiguous — the
id is the CCD/work month) then "…so it's the <next month> release, right?"
(felt like a contradiction, because a release is NAMED for its ship month =
CCD month + 1). Now it's ONE coherent confirmation that shows the ship-month
name and the CCD date together, so the user never picks a bare month and then
gets told it's a different one.
- New read-only `preview-release [--month] [--count] [--json]` command +
schedule helpers (month_add, preview_release, preview_releases) derive, for
the current month plus the next few, the ship-month display name and the
default CCD (2nd Wednesday) — no state, no IO.
- SKILL.md "start a release" reworked: lead with the computed default
("Start the October 2026 release — code-complete Wed Sep 9, 2026?"), offer
the alternatives by name + CCD; drop the separate post-init name-confirm.
- starting-and-scheduling.md: the name is confirmed up front, not re-asked;
set-target-month kept only as a rare override.
No engine behavior change (init/set-target-month untouched). Tests +4. 363 pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Swept all 130 files with vulture + pyflakes. Removed only confirmed-dead code and fixed two real latent bugs; held back tested-but-uncalled helpers. Dead code removed: - unreachable functions: engine._first_incomplete + _iter_steps (the latter orphaned once its only caller went), stub_runner.get_runner/REGISTRY (engine calls run_stub directly), checks.check_http (+ its urllib imports), oneauth_common_pr._pr_url, distribute._name_map. - unused imports across 10 modules (Optional, time, Orchestrator, _json, SELF_CHAT_ID, coords, Done, and the pipelines submodules' json/shutil/ subprocess/coords). Left intentional re-exports intact (lockdown's noqa line; _common's K.CHECKER_DEF/ORCH_* which siblings consume). Latent bugs fixed: - tools/pipelines/orchestrator.py had TWO orchestrator_stage_state defs; the second silently shadowed the first. Removed the dead get_stages version; the live, tested get_timeline one serves both callers. - schedule.py used Tuple in an annotation without importing it (masked by `from __future__ import annotations`) — added the import. Also dropped two empty f-string prefixes. 363 tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Return Done before rebuilding completed or skipped step actions, preserve original completion records, and refresh step-action after approval before sending. Reuse the existing step lifecycle without delivery-specific state or commands. Concurrent pending executions remain a separate follow-up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use StepState execution ownership for standard MCP actions completed through record-step. Keep interrupted work reserved for owner-reviewed recovery, preserve repeatable telemetry observations, and use OS-managed locks instead of age-based lock stealing. Update executor instructions and status guidance without introducing a delivery subsystem. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Have the existing hourly tick produce an independent Android Core Team alert at 9 AM on the last working day before CCD and again on CCD morning while Phase 0 remains incomplete. Include owner mention, blocker details and links, policy-safe resolution guidance, retry until successful delivery acknowledgement, and keep read-only notify observational. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Require declarative cleanup rules, separate startup and on-demand pollers, and centralize cleanup planning so workers delete live Scout automations before deregistering them. Cover CCD one-shots, localization timeout, RC settled state, Bug Bash completion/sign-off, final status, schedule sync, and release completion without migration logic for prior runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Persist APK build metadata and telemetry provenance; reject stale or mismatched result evidence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Prevent premature reports and false passes; align RC polling and email messaging with actual readiness. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Separate RC reporting, rendering, Authenticator verification and shared MRWP logic without changing behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ions Count each MRWP test once with any passing attempt winning; preserve complete source evidence and failure/recovery lists. Display Authenticator percentages to two decimals and a consolidated recommendation. Update knowledge and regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Project reconciled verdicts into plan configurations, preserve source provenance, and align current failure assignments and reminders. Update knowledge and regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Persist availability and preview evidence, reject stale assignment plans, and preserve agent step data through state transitions. Update skill guidance and regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Persist per-channel claims and acknowledgements, reject stale or expired delivery, finalize only after confirmed sends, and reconcile scope-aware cleanup. Route existing notification producers through the shared protocol and update knowledge, skill guidance and regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep release resource identities separate from step completion, bind checkpoints to the active release transaction, and reject incomplete or malformed paged reads. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Recover existing Broker plans instead of recreating them after errors. Route results by full tested configuration and retain Authenticator Monthly tests as report-only owner investigations. Separate source evidence, report preparation, mapping and durable fill receipts so distribution and progress consume published results without replaying earlier-phase logic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Filter owner, resolved on-call and permanent exclusions before availability choices. Keep blocked and failed automated cases in explicit owner triage, and align case assignees with plan testers without changing outcomes. Preserve preview approval and fail incomplete assignment alignment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use America/Los_Angeles regardless of owner or runner timezone, prevent overnight starts, and show the meeting-date UTC offset in invite previews and body text. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve the sent event ID through its Teams join URL to the exact meeting thread. Reject unrelated or stale chat bindings, enforce activation prerequisites, and bind both initial and recurring notifications to invitation evidence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.