feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose config, env file and records serve several, freezing each with --repo and --out. The run took the working directory for the repository under review: the prompt named it, the calibration was kept under it, and --trees fell back to it. The run now reads the repository from the artifact's freeze.json - the prompt names it and the calibration is kept under it - and --trees defaults to what the record says: the worktree, else the repository when it is not the working directory, else `.`, the same rule that builds the printed run line. The working directory keeps its roles: the config, the env file, the slots, the lens processes' cwd and every logged path. A damaged record stops the run at preflight.
This commit is contained in:
parent
ea4d362a10
commit
4fc15fe1c2
9 changed files with 133 additions and 14 deletions
|
|
@ -238,7 +238,7 @@ namespace Crafter::Review::Run {
|
|||
return {0, {}};
|
||||
}
|
||||
const fs::path root = scratchRoot && !scratchRoot->empty() ? *scratchRoot : fs::path(ScratchRoot(std::nullopt));
|
||||
const Memory::Calibration calib(root / "memory.json", repo, DefaultCosts());
|
||||
const Memory::Calibration calib(root / "memory.json", artifact ? Freeze::ReviewedBy(*artifact, repo).repo : repo, DefaultCosts());
|
||||
std::optional<Memory::Calibration::Cost> best;
|
||||
for (const std::string& e : appEnvs) {
|
||||
Memory::Calibration::Cost cost = calib.CostOf(e);
|
||||
|
|
@ -307,7 +307,7 @@ namespace Crafter::Review::Run {
|
|||
}
|
||||
|
||||
// ---- the Run ---------------------------------------------------------------------------
|
||||
Run::Run() : repo(fs::current_path()), t0(Platform::Now()) {
|
||||
Run::Run() : repo(fs::current_path()), reviewed(repo), t0(Platform::Now()) {
|
||||
log = [this](const std::string& message) { Message(message); };
|
||||
appReady = [](std::string_view url, std::string_view path) { return AppReady(url, path); };
|
||||
probe = [](std::string_view url) { return PgWire::Probe(url); };
|
||||
|
|
@ -483,6 +483,8 @@ namespace Crafter::Review::Run {
|
|||
}
|
||||
logFile = scratch / "log.txt";
|
||||
log(std::format("crafter-review {} prompt v{}: commits {} @ {}", Version(), PromptVersion, Dyn::RelPath(a.artifact, repo.string()), hash));
|
||||
std::error_code canonical;
|
||||
if (fs::weakly_canonical(reviewed, canonical) != fs::weakly_canonical(repo, canonical)) log(std::format("repository under review: {} (read at {})", reviewed.string(), trees.front()));
|
||||
log(std::format("config: {}", Dyn::Truthy(Dyn::Get(cfg, "_path")) ? Dyn::Str(cfg.at("_path")) : std::string("defaults (no .review-gates/config.json)")));
|
||||
for (const Json& w : Dyn::Or(Dyn::Get(cfg, "_warnings"), Dyn::EmptyList())) log(std::format("config: warning: {}", Dyn::Str(w)));
|
||||
std::vector<std::string> lensParts;
|
||||
|
|
@ -560,7 +562,7 @@ namespace Crafter::Review::Run {
|
|||
systemText = Prompt::SystemText();
|
||||
systemPaths.clear();
|
||||
systemByLens.clear();
|
||||
runLayer = Prompt::RunLayer(Dyn::RelPath(a.artifact, repo.string()), a.base, a.date, trees, hash, lines, units, contextPaths, Basename(repo));
|
||||
runLayer = Prompt::RunLayer(Dyn::RelPath(a.artifact, repo.string()), a.base, a.date, trees, hash, lines, units, contextPaths, Basename(reviewed));
|
||||
// The application under test: the login fixture, the TOTP helper.
|
||||
const Json& fcfg = cfg.at("functional");
|
||||
loginFixture = Config::LoginFixture(cfg, repo);
|
||||
|
|
@ -570,7 +572,7 @@ namespace Crafter::Review::Run {
|
|||
schemas = {{"block", Schema::SchemaJson("block")}, {"whole", Schema::SchemaJson("whole")}};
|
||||
// Memory: every pass's tree measured, its peak recorded per repository
|
||||
// and environment; the budget per gate.
|
||||
calibration = std::make_unique<Memory::Calibration>(scratchRoot / "memory.json", repo, DefaultCosts());
|
||||
calibration = std::make_unique<Memory::Calibration>(scratchRoot / "memory.json", reviewed, DefaultCosts());
|
||||
if (!a.dryRun) {
|
||||
// A pass runs under the supervisor: its tree is claude's, the
|
||||
// supervisor itself left out, so a peak measures claude's tree
|
||||
|
|
@ -1685,7 +1687,14 @@ namespace Crafter::Review::Run {
|
|||
|
||||
// ---- the run ------------------------------------------------------------------------------
|
||||
std::int32_t Run::Execute() {
|
||||
trees = CommaList(a.trees.value_or("."));
|
||||
Freeze::Reviewed frozen;
|
||||
try {
|
||||
frozen = Freeze::ReviewedBy(a.artifact, repo);
|
||||
} catch (const std::runtime_error& e) {
|
||||
Die(e.what());
|
||||
}
|
||||
reviewed = frozen.repo;
|
||||
trees = CommaList(a.trees.value_or(frozen.tree));
|
||||
contextPaths = CommaList(a.contextPaths);
|
||||
for (const std::string& c : contextPaths) {
|
||||
if (!fs::exists(c)) Die(std::format("--context-paths: {} does not exist", c));
|
||||
|
|
|
|||
Loading…
Reference in a new issue