Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion docs/conceptual/optimization-loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,10 @@ One phase, two levers worked in parallel:
a specialist wrote, `upstream_pr` for a diff fetched from an upstream PR
that a `candidate_discovery_specialist` found, ranked and judged. Both
serialise on the `workspace_mutation` lane: one landing at a time,
independent of how fast proposals arrive.
independent of how fast proposals arrive. A candidate whose every patch
reverse-applies cleanly, and that changes nothing else, is not benchmarked:
it ends `already_present`, and a candidate with an upstream PR identity is
recorded so in the framework KB.

`specialist` serves both levers — investigation, patch authoring, and
candidate discovery are all dispatches of the one specialist action. An
Expand Down
12 changes: 6 additions & 6 deletions scripts/code_metrics_baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patc
cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._enablement_keep_records 38
cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._gate_enablement 31
cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._gate_perf 101
cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_apply 131
cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_apply 110
cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::_resolve_patch_paths 36
cognitive-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::restore_pending_integrate 83
cognitive-complexity src/hyperloom/orchestrator/actions/executors/profile.py::ProfileExecutor.__call__ 235
Expand Down Expand Up @@ -302,7 +302,7 @@ cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/baseline.py::
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/benchmark_result.py::harvest_mn_gpu_metrics 30
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/explore.py::ExploreExecutor.__call__ 76
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._gate_perf 29
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_apply 53
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_apply 45
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/integrate_patch.py::restore_pending_integrate 25
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/profile.py::ProfileExecutor.__call__ 66
cyclomatic-complexity src/hyperloom/orchestrator/actions/executors/profile.py::_validate_trace_structure 28
Expand Down Expand Up @@ -552,7 +552,7 @@ function-lines src/hyperloom/orchestrator/actions/executors/_multi_node_server_l
function-lines src/hyperloom/orchestrator/actions/executors/_multi_node_server_lifecycle.py::_wait_for_server_health_async 188
function-lines src/hyperloom/orchestrator/actions/executors/_multi_node_server_lifecycle.py::_wait_for_workers_ready_async 97
function-lines src/hyperloom/orchestrator/actions/executors/_multi_node_server_lifecycle.py::restart_server_for_round 269
function-lines src/hyperloom/orchestrator/actions/executors/_nogit_patch.py::_apply_patch_no_git 169
function-lines src/hyperloom/orchestrator/actions/executors/_nogit_patch.py::_apply_patch_no_git 167
function-lines src/hyperloom/orchestrator/actions/executors/_partition_shape.py::validate_session_shape 127
function-lines src/hyperloom/orchestrator/actions/executors/_patch_snapshot.py::replayed_stack_ops 81
function-lines src/hyperloom/orchestrator/actions/executors/_patch_source_pr.py::materialize_candidate_patches 96
Expand All @@ -571,7 +571,7 @@ function-lines src/hyperloom/orchestrator/actions/executors/baseline.py::Benchma
function-lines src/hyperloom/orchestrator/actions/executors/baseline.py::BenchmarkRunExecutor._run_once 682
function-lines src/hyperloom/orchestrator/actions/executors/baseline.py::BenchmarkRunExecutor._run_retrying 97
function-lines src/hyperloom/orchestrator/actions/executors/baseline.py::BenchmarkRunExecutor._run_single_benchmark 578
function-lines src/hyperloom/orchestrator/actions/executors/baseline.py::_apply_warm_patches 416
function-lines src/hyperloom/orchestrator/actions/executors/baseline.py::_apply_warm_patches 414
function-lines src/hyperloom/orchestrator/actions/executors/benchmark_result.py::extract_benchmark_measurement 135
function-lines src/hyperloom/orchestrator/actions/executors/benchmark_result.py::harvest_leaked_artifacts 85
function-lines src/hyperloom/orchestrator/actions/executors/benchmark_result.py::harvest_mn_gpu_metrics 122
Expand All @@ -586,7 +586,7 @@ function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._gate_perf 445
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._keep_inert_switches 111
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._maybe_write_framework_kb_record 114
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_apply 509
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_apply 477
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_gate 84
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_provision_attempt_runtime 105
function-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py::IntegratePatchExecutor._stage_resolve 123
Expand Down Expand Up @@ -941,7 +941,7 @@ module-lines src/hyperloom/orchestrator/actions/executors/_multi_node_server_lif
module-lines src/hyperloom/orchestrator/actions/executors/_workload_envs.py 2261
module-lines src/hyperloom/orchestrator/actions/executors/baseline.py 4253
module-lines src/hyperloom/orchestrator/actions/executors/explore.py 1880
module-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py 4799
module-lines src/hyperloom/orchestrator/actions/executors/integrate_patch.py 4690
module-lines src/hyperloom/orchestrator/actions/executors/profile.py 1565
module-lines src/hyperloom/orchestrator/actions/executors/report.py 1391
module-lines src/hyperloom/orchestrator/actions/executors/roofline.py 1303
Expand Down
7 changes: 5 additions & 2 deletions src/hyperloom/inference_optimizer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,11 @@ with that off too, the source arm reports itself dry.

Every diff lands through `integrate_patch`, with `patch_source` naming where
it came from. KEEP commits to the live tree so the next candidate stacks on
top; REVERT does `git reset --hard`. Resume skips completed candidates by
idempotency key.
top; REVERT does `git reset --hard`. A candidate the tree already holds is not
benchmarked: when every patch in the set reverse-applies cleanly and the round
changes nothing else, it ends `already_present`, with that evidence on the
result and, for a candidate with an upstream PR identity, an `already_present`
row in the framework KB. Resume skips completed candidates by idempotency key.

The phase exits when both arms are dry, when its budget is spent, or at the
absolute per-phase cap.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ delegate{
cleanly. A patch that does not apply, and is not already in the tree,
is REVERT-immediate (record `apply_failed`); a failed apply leaves the
tree untouched, and the revert resets it to the HEAD recorded before
the attempt.
the attempt. When every patch is already in the tree and the task
changes nothing else, the action ends `already_present` here: no
restart, no benchmark.
4. Layer `config_changes` onto the server-launch env.
5. Stop the server this session launched, by the pid and process group it
recorded; wait for VRAM to drain. No pattern-based kill runs.
Expand All @@ -88,7 +90,7 @@ delegate{

```
{
"status": "kept" | "reverted" | "apply_failed",
"status": "kept" | "reverted" | "apply_failed" | "already_present",
"output_throughput": <float | null>,
"delta_pct": <float | null>,
"accuracy_pass": <bool | null>,
Expand All @@ -112,6 +114,7 @@ hash and `optimization_stack` is the authoritative ledger.
| Symptom | Cause | Mitigation |
|---|---|---|
| `git apply` rejects | base HEAD drifted under specialist | reject patch, record `apply_failed`, REVERT path |
| every patch is already in the tree | the change landed upstream or in an earlier round | `already_present`, with the reverse check per patch under `already_present`; framework KB row `already_present` when the candidate carries an upstream PR identity |
| server fails to start | broken patch | `git checkout` + restart prior config, mark REVERT |
| accuracy drops >0.05 absolute | semantic regression | REVERT, record into pitfalls KB |
| throughput unchanged within keep_threshold | no-op patch | REVERT, log low-confidence specialist for the gap |
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ def test_collect_framework_agent_candidate_priors(coord: Coordinator) -> None:
assert denied["rationale"] == "off the bottleneck"


def test_an_already_present_candidate_counts_as_tested() -> None:
"""It reached the apply stage, so the phase summary does not read it as a discovery that found nothing."""
from hyperloom.orchestrator.framework.artifacts import summarize_candidate_outcomes

summary = summarize_candidate_outcomes([{"candidate_id": "c1", "status": "already_present", "kept": False}])
assert summary["tested"] == 1
assert summary["outcome_class"] == "tested_no_keep"


# _match_framework_agent_candidate


Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# SPDX-FileCopyrightText: 2026 Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT

"""Structured apply-failure feedback for patch reauthoring."""
"""Per-patch apply results, and the structured failure feedback used for reauthoring."""

from __future__ import annotations

import logging
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import Any

Expand All @@ -15,6 +16,15 @@
log = logging.getLogger(__name__)


class PresenceCheck(Enum):
"""How a change was found already in the tree, so applying it would change nothing."""

#: ``git apply -R --check`` passes: every hunk's post-image is in the checkout.
GIT_REVERSE_APPLY = "git_reverse_apply_check"
#: ``patch -R --fuzz=0 --dry-run`` passes with no offset: the same proof without git.
PATCH_REVERSE_DRY_RUN = "patch_reverse_dry_run"


@dataclass
class ApplyFeedback:
"""Structured feedback from a failed patch apply attempt."""
Expand Down Expand Up @@ -64,6 +74,20 @@ def format_for_mandate(self) -> str:
return "\n".join(parts)


@dataclass(frozen=True)
class PatchApplyResult:
"""What applying one patch did: changed the tree, found it already there, or failed."""

ok: bool
error: str = ""
#: Backup records the plain-``patch`` channel wrote before changing files; a git apply keeps none.
backups: list[dict[str, Any]] = field(default_factory=list)
#: Reauthoring feedback for a failure.
feedback: ApplyFeedback | None = None
#: The check that found every hunk already in the tree, when the apply changed nothing.
present_by: PresenceCheck | None = None


def read_patch_source_context(
patch_text: str,
framework_root: Path,
Expand Down Expand Up @@ -194,6 +218,8 @@ def build_apply_feedback(

__all__ = [
"ApplyFeedback",
"PatchApplyResult",
"PresenceCheck",
"build_apply_feedback",
"read_patch_source_context",
"source_context_for_file",
Expand Down
94 changes: 61 additions & 33 deletions src/hyperloom/orchestrator/actions/executors/_nogit_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

from ...delivery.ledger import append_record, mark_prepared
from ...delivery import file_digest as _file_digest
from ...specialists.patch_safety import patch_file_targets, path_resolves_at
from ._apply_feedback import ApplyFeedback, PatchApplyResult, PresenceCheck, read_patch_source_context

log = logging.getLogger(__name__)

Expand All @@ -26,6 +28,9 @@

_PATCH_DEV_NULL = "/dev/null"

# Patch and reject files are read leniently: one undecodable byte must not hide the rest.
_DECODE_ERRORS = "replace"

# Characters unsafe in filenames (replaced with ``_`` in rel_flat).
_UNSAFE_NAME_RE = re.compile(r"[/\\:<>\"?*|]")

Expand Down Expand Up @@ -84,6 +89,31 @@ def _is_git_tree(path: Path) -> bool:
return False


def _reverse_probe_levels(framework_root: Path, patch_path: Path) -> tuple[int, ...]:
"""The ``-p`` levels at which a clean reverse check shows ``patch_path`` is already applied.

Undoing a file deletion creates the file, which succeeds at any level where
the stripped path happens to be absent, so a level counts only when some
file the patch names resolves at it, read from the ``---``/``+++`` headers
as the target preflight reads them. A deletion already carried out leaves
nothing to resolve, and then every level counts.

Args:
framework_root: The source-tree root the patch targets.
patch_path: The unified-diff patch file to probe.

Returns:
The levels to probe, in priority order; none when the patch cannot be read.
"""
try:
pairs = patch_file_targets(patch_path.read_text(encoding="utf-8", errors=_DECODE_ERRORS))
except OSError:
return ()
paths = {path for pair in pairs for path in pair if path != _PATCH_DEV_NULL}
anchored = tuple(lvl for lvl in _P_LEVELS if any(path_resolves_at(framework_root, p, lvl) for p in paths))
return anchored or _P_LEVELS


def _reverse_applies_cleanly(framework_root: Path, patch_path: Path) -> bool:
"""True when ``patch_path`` is already fully applied in ``framework_root``.

Expand All @@ -97,7 +127,7 @@ def _reverse_applies_cleanly(framework_root: Path, patch_path: Path) -> bool:
the post-image even though every hunk found a home.

Strictly a probe: ``--dry-run`` is passed at every level, so the tree is
never mutated.
never mutated. Only the levels :func:`_reverse_probe_levels` names are tried.

Args:
framework_root: The source-tree root the patch targets.
Expand All @@ -106,7 +136,7 @@ def _reverse_applies_cleanly(framework_root: Path, patch_path: Path) -> bool:
Returns:
``True`` when the tree exactly holds the patch's post-state.
"""
for lvl in _P_LEVELS:
for lvl in _reverse_probe_levels(framework_root, patch_path):
try:
cp = subprocess.run(
# ``--fuzz=0``: an approximate context match would answer yes
Expand Down Expand Up @@ -144,7 +174,7 @@ def _rejected_hunks(reject_path: Path) -> str:
"""The hunk bodies ``patch`` could not apply; empty when it failed before rejecting any."""
if not reject_path.exists():
return ""
return reject_path.read_text(encoding="utf-8", errors="replace").strip()
return reject_path.read_text(encoding="utf-8", errors=_DECODE_ERRORS).strip()


def _apply_patch_no_git(
Expand All @@ -153,19 +183,16 @@ def _apply_patch_no_git(
backup_root: Path,
*,
seq_offset: int = 0,
) -> "tuple[bool, str, list[dict[str, Any]], Any]":
) -> PatchApplyResult:
"""Apply ``patch_path`` into ``framework_root`` without git, backing up targets."""
from ._apply_feedback import ApplyFeedback, read_patch_source_context

try:
patch_text = patch_path.read_text(encoding="utf-8", errors="replace")
patch_text = patch_path.read_text(encoding="utf-8", errors=_DECODE_ERRORS)
except OSError as exc:
err_msg = f"cannot read patch file: {exc}"
return (
False,
err_msg,
[],
ApplyFeedback(patch=str(patch_path), channel="nogit", tried_levels=[], stderr=err_msg),
return PatchApplyResult(
ok=False,
error=err_msg,
feedback=ApplyFeedback(patch=str(patch_path), channel="nogit", tried_levels=[], stderr=err_msg),
)

# Feed the CLI a copy with contradicting index headers removed; keep the original path in feedback so advisories
Expand Down Expand Up @@ -208,7 +235,7 @@ def _apply_patch_no_git(
tried_levels=tried_levels,
stderr=err_msg,
)
return False, err_msg, [], feedback
return PatchApplyResult(ok=False, error=err_msg, feedback=feedback)
dry_run_stderrs.append(f"-p{lvl}: {cp.stderr.strip()}" if cp.stderr.strip() else f"-p{lvl}: (no stderr)")
if cp.returncode == 0:
detected_level = lvl
Expand All @@ -227,23 +254,24 @@ def _apply_patch_no_git(
# A clean *reverse* dry-run is the unambiguous already-applied probe: it
# succeeds only when every hunk's post-state is already present in the
# tree, which is exactly the state a forward apply would produce. In that
# case the apply is a satisfied no-op -- report success with no backups
# (the patch that really made those edits owns the backups needed for a
# correct revert).
# case the apply is a satisfied no-op -- report it as present, with no
# backups (the patch that really made those edits owns the backups needed
# for a correct revert).
if _reverse_applies_cleanly(framework_root, patch_input):
if not mark_prepared(backup_root):
err_msg = "backup prepare record could not be persisted"
return (
False,
err_msg,
[],
ApplyFeedback(patch=str(patch_path), channel="nogit", tried_levels=tried_levels, stderr=err_msg),
return PatchApplyResult(
ok=False,
error=err_msg,
feedback=ApplyFeedback(
patch=str(patch_path), channel="nogit", tried_levels=tried_levels, stderr=err_msg
),
)
log.info(
"nogit patch: %s is already fully applied (clean reverse dry-run); treating as a no-op",
patch_path.name,
)
return True, "", [], None
return PatchApplyResult(ok=True, present_by=PresenceCheck.PATCH_REVERSE_DRY_RUN)
combined_stderr = "\n".join(dry_run_stderrs)
err_msg = f"patch --dry-run failed at all strip levels for {patch_path.name}"
source_ctx = read_patch_source_context(patch_text, framework_root, radius=50)
Expand All @@ -254,15 +282,15 @@ def _apply_patch_no_git(
stderr=combined_stderr,
source_context=source_ctx,
)
return False, err_msg, [], feedback

def _fail(err_message: str, recs: list[dict[str, Any]]) -> "tuple[bool, str, list[dict[str, Any]], Any]":
"""Return the canonical 4-tuple failure result with structured feedback."""
return (
False,
err_message,
recs,
ApplyFeedback(
return PatchApplyResult(ok=False, error=err_msg, feedback=feedback)

def _fail(err_message: str, recs: list[dict[str, Any]]) -> PatchApplyResult:
"""Return the failure result with structured feedback."""
return PatchApplyResult(
ok=False,
error=err_message,
backups=recs,
feedback=ApplyFeedback(
patch=str(patch_path),
channel="nogit",
tried_levels=tried_levels,
Expand Down Expand Up @@ -364,8 +392,8 @@ def _backup_existing(abs_path: Path, rel: Path) -> tuple[dict[str, Any] | None,
rejected_hunks=rejected_hunks,
source_context=source_ctx,
)
return False, apply_stderr, backups, feedback
return True, "", backups, None
return PatchApplyResult(ok=False, error=apply_stderr, backups=backups, feedback=feedback)
return PatchApplyResult(ok=True, backups=backups)


__all__ = [
Expand Down
Loading