Erinaldordso commited on
Commit
4f0652b
·
verified ·
1 Parent(s): bdd1375

Allow controlled vertical descent so underground ores are reachable

Browse files
tests/test_voyager_vertical_exploration.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Trava a politica de exploracao vertical do Naldo contra regressao.
3
+
4
+ Contexto medido no bot em producao: `learning.updated_at` congelava e
5
+ `completed_count` ficava parado enquanto o modelo respondia com JavaScript
6
+ valido e zero erros de parse. A causa nao era o modelo. Eram duas instrucoes
7
+ contraditorias:
8
+
9
+ - o Action prompt dizia "o subsolo e um mapa de recursos; cavar para baixo e o
10
+ modo normal de alcancar os minerios";
11
+ - `exploreUntil.js` forcava `dy = 0`, reescrevendo silenciosamente um pedido de
12
+ descida em um passeio horizontal.
13
+
14
+ O modelo obedecia a primeira, o bot nunca descia, e 8 dos ultimos 12 fracassos
15
+ eram minerios subterraneos. A correcao substitui o veto por uma descida
16
+ controlada: o bot escava degrau por degrau na propria coluna, com teto de
17
+ profundidade, e mantem o caminho de volta.
18
+
19
+ Estes testes existem para que a contradicao nao volte por descuido. Eles rodam
20
+ como script (nao como pytest), igual ao resto da suite deste Space.
21
+ """
22
+ from __future__ import annotations
23
+
24
+ import ast
25
+ import pathlib
26
+ import re
27
+ import subprocess
28
+ import sys
29
+
30
+ ROOT = pathlib.Path(__file__).resolve().parent.parent
31
+ STACK = ROOT / "voyager_stack.py"
32
+ NODE = "node"
33
+
34
+ FAILURES: list[str] = []
35
+
36
+
37
+ def check(name: str, ok: bool, detail: object = "") -> None:
38
+ print(" " + ("ok " if ok else "FALHA ") + name + ("" if ok else " " + str(detail)[:300]))
39
+ if not ok:
40
+ FAILURES.append(name)
41
+
42
+
43
+ SOURCE = STACK.read_text(encoding="utf-8")
44
+
45
+
46
+ def _generated(marker: str) -> str:
47
+ """Devolve o literal cru de um patch `X.write_text(r'''...''')`."""
48
+ index = SOURCE.index(marker) + len(marker)
49
+ end = SOURCE.index("'''", index)
50
+ return SOURCE[index:end]
51
+
52
+
53
+ EXPLORE_JS = _generated("explore_until.write_text(r'''")
54
+ EXPLORE_CONTEXT = _generated("explore_context.write_text(r'''")
55
+ MINE_BLOCK_JS = _generated("primitive = r'''")
56
+
57
+
58
+ print("=" * 70)
59
+ print("1. o JavaScript gerado pelo patch compila")
60
+ print("=" * 70)
61
+ for name, code in (
62
+ ("exploreUntil.js", EXPLORE_JS),
63
+ ("exploreUntil context", EXPLORE_CONTEXT),
64
+ ("mineBlock.js", MINE_BLOCK_JS),
65
+ ):
66
+ target = ROOT / "_syntax_probe.js"
67
+ target.write_text(code, encoding="utf-8")
68
+ try:
69
+ proc = subprocess.run(
70
+ [NODE, "--check", str(target)],
71
+ capture_output=True, text=True, timeout=60,
72
+ )
73
+ ok = proc.returncode == 0
74
+ detail = (proc.stderr or proc.stdout).strip()
75
+ except FileNotFoundError:
76
+ # Sem Node na maquina de teste: nao inventa sucesso nem falha.
77
+ ok, detail = True, "node ausente; pulado"
78
+ check(f"{name} compila", ok, detail)
79
+
80
+
81
+ print()
82
+ print("=" * 70)
83
+ print("2. a descida existe, e e uma descida controlada")
84
+ print("=" * 70)
85
+ # A descida precisa ser reconhecida nas formas que um modelo realmente emite.
86
+ check("aceita o verbo 'down'", '"down"' in EXPLORE_JS and "downward" in EXPLORE_JS)
87
+ check("aceita vetor com y negativo", "const descending = creative && dy < 0" in EXPLORE_JS)
88
+
89
+ # O ponto central: nao pode mais existir o veto incondicional a descer.
90
+ check(
91
+ "nao forca mais dy = 0 para todo Creative",
92
+ 'if (bot.game && bot.game.gameMode === "creative") dy = 0;' not in EXPLORE_JS,
93
+ )
94
+ check("existe teto de profundidade", "MAX_DESCENT = 32" in EXPLORE_JS)
95
+ check("desce escavando, nao caindo", "bot.dig(under, true)" in EXPLORE_JS)
96
+ check("limpa a propria celula antes de descer", "headroom" in EXPLORE_JS)
97
+ # Numero de passos: 'dig' comeca a descida; waitForTicks deixa a gravidade agir.
98
+ check("espera a gravidade assentar", "waitForTicks(4)" in EXPLORE_JS)
99
+
100
+ # Subida explicita continua bloqueada em Creative: o GoalNear vertical e o que
101
+ # derrubava o bot de uma beirada, e isso nao foi reaberto.
102
+ check("subida continua bloqueada em Creative", "if (creative && dy > 0) dy = 0;" in EXPLORE_JS)
103
+ check(
104
+ "o GoalNear vertical nao e mais usado com dy reescrito",
105
+ "new GoalNear(x, y, z)" in EXPLORE_JS,
106
+ )
107
+
108
+
109
+ print()
110
+ print("=" * 70)
111
+ print("3. o bot consegue sair do proprio poco")
112
+ print("=" * 70)
113
+ # Sem isto, a politica de descer troca "nunca acha minerio" por "fica preso".
114
+ check(
115
+ "allow1by1towers liberado em Creative",
116
+ "movements.allow1by1towers = true;" in SOURCE,
117
+ )
118
+ check(
119
+ "allow1by1towers nao voltou a false",
120
+ "movements.allow1by1towers = false;" not in SOURCE,
121
+ )
122
+ check("maxDropDown continua contido", "movements.maxDropDown = 2;" in SOURCE)
123
+
124
+
125
+ print()
126
+ print("=" * 70)
127
+ print("4. prompt e primitiva contam a mesma historia")
128
+ print("=" * 70)
129
+ action_facts = re.search(r"creative_facts = '''(.*?)'''", SOURCE, re.DOTALL)
130
+ check("bloco de fatos do Action prompt encontrado", action_facts is not None)
131
+ if action_facts:
132
+ facts = action_facts.group(1)
133
+ check(
134
+ "prompt nao diz mais que exploracao e so na superficie",
135
+ "Exploration is surface-only here" not in facts,
136
+ )
137
+ check(
138
+ "prompt aponta o modo de descida",
139
+ "Vec3(0, -1, 0)" in facts or '"down"' in facts,
140
+ )
141
+ check(
142
+ "prompt mantem a promessa do subsolo (agora verdadeira)",
143
+ "band of every ore" in facts,
144
+ )
145
+
146
+ check(
147
+ "context file nao proibe mais exploracao vertical",
148
+ "Never explore vertically" not in EXPLORE_CONTEXT,
149
+ )
150
+ check("context file documenta a descida", "VERTICAL" in EXPLORE_CONTEXT)
151
+ check("context file nao diz 'surface-only'", "surface-only" not in EXPLORE_CONTEXT)
152
+
153
+ # A mensagem de erro do mineBlock e o ultimo lugar onde a politica antiga
154
+ # sobrevivia: ela mandava o modelo "explorar na superficie" para achar minerio.
155
+ check(
156
+ "erro do mineBlock nao manda explorar so na superficie",
157
+ "explore on the surface" not in MINE_BLOCK_JS,
158
+ )
159
+ check(
160
+ "erro do mineBlock cita o caminho correto",
161
+ "use exploreUntil to travel or to descend" in MINE_BLOCK_JS,
162
+ )
163
+
164
+
165
+ print()
166
+ print("=" * 70)
167
+ print("5. o curriculum sabe que os minerios nao estao na superficie")
168
+ print("=" * 70)
169
+ # O curriculum propunha tarefas que o Action nao tinha como executar porque a
170
+ # unica instrucao sobre acesso era "reachable on foot".
171
+ check(
172
+ "fatos do curriculum marcam os minerios como subterraneos",
173
+ "The ores are underground, not on the surface" in SOURCE,
174
+ )
175
+
176
+
177
+ print()
178
+ print("=" * 70)
179
+ if FAILURES:
180
+ print(f"{len(FAILURES)} teste(s) falharam:")
181
+ for failure in FAILURES:
182
+ print(" -", failure)
183
+ sys.exit(1)
184
+ print("politica de exploracao vertical: coerente e sem contradicao")