chore: snapshot pre-v0.2.0 WIP (pathfinder/reflex/metrics/skills improvements)

Baseline for the v0.2.0 self-learning iteration. All 205 tests pass on this
state. Subsequent commits in this branch layer the knowledge base,
post-mortem coach, and persona narration on top.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 13:05:12 +03:00
co-authored by Claude Opus 4.7
parent 3ee2ab886e
commit 86e5294bb8
30 changed files with 1023 additions and 130 deletions
@@ -100,6 +100,38 @@ test("tunnel-out does not count jumping in place as escape", async () => {
assert.match(res.detail.error, /moved only 0\.00 horizontally/);
});
test("tunnel-out digs one reachable layer at a time", async () => {
const blocks = {};
for (let step = 1; step <= 3; step++) {
blocks[`${step},64,0`] = "stone";
blocks[`${step},65,0`] = "stone";
blocks[`${step},63,0`] = "stone";
}
blocks["0,64,-1"] = "oak_planks";
blocks["0,64,1"] = "oak_planks";
blocks["-1,64,0"] = "oak_planks";
const bot = makeBot(blocks);
bot.look = async () => {};
bot.lookAt = async () => {};
bot.dig = async (block) => {
const dist = Math.hypot(block.position.x - bot.entity.position.x, block.position.z - bot.entity.position.z);
if (dist > 1.5) throw new Error(`too far: ${dist.toFixed(1)}`);
blocks[`${block.position.x},${block.position.y},${block.position.z}`] = "air";
};
bot.setControlState = (control, on) => {
if (control === "forward" && !on) {
bot.entity.position = makePos(bot.entity.position.x + 1, bot.entity.position.y, bot.entity.position.z);
}
};
const res = await digEscapeTunnel(bot, { maxSteps: 3, minMove: 0.75, pushMs: 0 });
assert.equal(res.ok, true);
assert.equal(res.detail.dir, "E");
assert.equal(res.detail.dug, 6);
assert.equal(Math.round(bot.entity.position.x), 3);
});
test("explore.far blind fallback does not report done when position is unchanged", async () => {
const blocks = {};
const bot = makeBot(blocks);