idea_world_labDEV JOURNAL
sábado, 27 de junho de 2026

Fluxo de rastreamento de linha do código-fonte ao AST e ao Retriever

Data de criação: 27 de junho de 2026

Objetivo

Este documento reorganiza, com base no dia 27, a parte que havia perdido consistência em docs/roadmaps/2026-06-26-source-to-ast-input-flow.md.

O ponto central não é redefinir a nova unidade de design. A arquitetura completa e a direção do design do banco de dados já foram documentadas separadamente. Aqui rastreamos até o fim qual linha de qual arquivo entra no Parser de AST quando a entrada real é recebida, qual fragmento é usado na busca do Retriever e quais candidatos de evidência retornam para a decisão do LLM.

O princípio a ser mantido é simples.

O caminho do arquivo é anexado para rastrear a localização.  
No Retriever, não são caminhos de arquivo, mas trechos de código/texto que são inseridos.  
Arquivos .gd são cortados pelo AST Parser em unidades de funções e declarações.  
Outros arquivos de texto necessários são cortados diretamente por intervalo de linhas.  
Cada trecho passa sequencialmente pelo Retriever e pela avaliação do LLM.

Forma de entrada

Ao clonar ou fazer upload do projeto, primeiro expanda os arquivos com o caminho relativo.

Ele aparece da seguinte forma.

# <caminho relativo>
<conteúdo do arquivo>

# <caminho relativo>
<conteúdo do arquivo>

Esta notação serve para depuração humana. Cabeçalhos como # player.gd são apenas indicadores que mostram “de qual arquivo vem o conteúdo abaixo”.

A pesquisa Retriever não inclui # player.gd. O AST Parser também não inclui # player.gd. O que é incluído é o conteúdo real do arquivo abaixo do cabeçalho.

Entrada de exemplo

A seguir está a visualização de um pequeno projeto Godot. Números como E001, E002 são apenas números de linha para explicação e não fazem parte do texto de entrada real.

E001 # project.godot
E002 config_version=5
E003
E004 [application]
E005 config/name="Mini Dodge"
E006 run/main_scene="res://player.tscn"
E007
E008 # player.gd
E009 extends Area2D
E010
E011 signal hit
E012
E013 @export var speed = 400
E014 var screen_size
E015
E016 func _ready():
E017 	screen_size = get_viewport_rect().size
E018 	hide()
E019
E020 func _process(delta):
E021 	var velocity = Vector2.ZERO
E022 	if Input.is_action_pressed(&"move_right"):
E023 		velocity.x += 1
E024 	if Input.is_action_pressed(&"move_left"):
E025 		velocity.x -= 1
E026
E027 	if velocity.length() > 0:
E028 		velocity = velocity.normalized() * speed
E029 		$AnimatedSprite2D.play()
E030 	else:
E031 		$AnimatedSprite2D.stop()
E032
E033 	position += velocity * delta
E034 	position = position.clamp(Vector2.ZERO, screen_size)
E035
E036 func start(pos):
E037 	position = pos
E038 	show()
E039 	$CollisionShape2D.disabled = false
E040
E041 # player.tscn
E042 [gd_scene load_steps=3 format=3 uid="uid://mini"]
E043
E044 [ext_resource type="Script" path="res://player.gd" id="1"]
E045
E046 [node name="Player" type="Area2D"]
E047 script = ExtResource("1")

1ª Etapa: Dividir Limites de Arquivo

Primeiro, divida os arquivos com base no cabeçalho # <caminho relativo>.

project.godot começa em E001. O conteúdo real vai de E002 a E006. E001 é apenas um marcador de limite de arquivo, portanto não faz parte do conteúdo analisado.

player.gd começa em E008. O conteúdo real vai de E009 a E039. E008 é apenas um marcador de limite de arquivo, portanto não entra no AST Parser.

player.tscn começa em E041. O conteúdo real vai de E042 a E047. E041 é apenas um marcador de limite de arquivo, portanto não faz parte da busca do Retriever.

Nessa etapa, a UI pode mostrar algo como “processando E009‑E039 do player.gd”. Contudo, ainda não se cria a palavra‑chave de busca.

2ª Etapa: Definir Direção de Processamento por Tipo de Arquivo

player.gd é um arquivo GDScript. Portanto, todo o intervalo E009‑E039 é enviado ao AST Parser.

project.godot é um arquivo de configuração. Não é enviado ao AST Parser; em vez disso, é fragmentado diretamente por seções necessárias.

player.tscn é um arquivo de cena. Não é enviado ao AST Parser; em vez disso, é fragmentado diretamente por blocos de node/resource.

Arquivos README ou documentos Markdown são, por padrão, excluídos no modo de análise de código‑fonte. Mesmo os arquivos excluídos devem aparecer na UI, pois é necessário que a pessoa verifique “o que está faltando”.

Por exemplo, se houver um README.md, ele será excluído da análise e a razão exibida será “arquivos de documentação são excluídos por padrão no modo de análise de código‑fonte”. Essa decisão de exclusão é apenas o padrão do modo de análise; se mais tarde for necessário um modo que também leia documentos, isso será tratado separadamente.

3ª Etapa: Enviar Arquivo .gd ao AST Parser

A entrada que vai do player.gd para o AST Parser são os trechos E009‑E039.

Na prática, o conteúdo que o AST Parser recebe é o seguinte.

extends Area2D

signal hit

@export var speed = 400
var screen_size

func _ready():
	screen_size = get_viewport_rect().size
	hide()

func _process(delta):
	var velocity = Vector2.ZERO
	if Input.is_action_pressed(&"move_right"):
		velocity.x += 1
	if Input.is_action_pressed(&"move_left"):
		velocity.x -= 1

	if velocity.length() > 0:
		velocity = velocity.normalized() * speed
		$AnimatedSprite2D.play()
	else:
		$AnimatedSprite2D.stop()

	position += velocity * delta
	position = position.clamp(Vector2.ZERO, screen_size)

func start(pos):
	position = pos
	show()
	$CollisionShape2D.disabled = false

Aqui não há # player.gd.

O AST Parser lê este texto de cima para baixo e o divide em unidades de declaração e função.

O primeiro fragmento é uma linha E009.

extends Area2D

A segunda peça é uma linha E011.

signal hit

A terceira peça é E013-E014.

@export var speed = 400
var screen_size

O quarto fragmento é E016-E018.

func _ready():
	screen_size = get_viewport_rect().size
	hide()

O quinto fragmento é E020-E034.

func _process(delta):
	var velocity = Vector2.ZERO
	if Input.is_action_pressed(&"move_right"):
		velocity.x += 1
	if Input.is_action_pressed(&"move_left"):
		velocity.x -= 1

	if velocity.length() > 0:
		velocity = velocity.normalized() * speed
		$AnimatedSprite2D.play()
	else:
		$AnimatedSprite2D.stop()

	position += velocity * delta
	position = position.clamp(Vector2.ZERO, screen_size)

A sexta peça é E036‑E039.

func start(pos):
	position = pos
	show()
	$CollisionShape2D.disabled = false

Importante que o fragmento, depois de criado, não perca o intervalo de linhas original. Por exemplo, o fragmento _process continua sendo rastreado como “fragmento extraído de player.gd nas linhas E020‑E034”.

4ª etapa: Processamento manual de fragmentos

Se for necessário dividir também arquivos de texto que não são alvos do AST Parser, faça isso em fragmentos.

No project.godot, as linhas E004‑E006 correspondem ao fragmento de configuração da aplicação.

[application]
config/name="Mini Dodge"
run/main_scene="res://player.tscn"

Esta parte pode ser usada para encontrar a cena inicial do projeto devido a run/main_scene="res://player.tscn". Se for feita uma pesquisa no Retriever, termos como run/main_scene, res://player.tscn e application presentes no texto servirão como material de busca. O próprio caminho do arquivo project.godot não se torna um termo de pesquisa.

No player.tscn, a linha E044 torna‑se um fragmento de referência ao script.

[ext_resource type="Script" path="res://player.gd" id="1"]

E046-E047 se tornam fragmentos de nó.

[node name="Player" type="Area2D"]
script = ExtResource("1")

Esse tipo de fragmento direto não é um chunk de AST, mas o fluxo subsequente é o mesmo. Usa‑se parte do corpo do texto para buscar no Retriever, e o LLM verifica novamente os candidatos encontrados.

Etapa 5: O que realmente entra no Retriever

No Retriever não são inseridos “caminhos de arquivo”, mas sim “o corpo do fragmento atual e as pistas de busca extraídas do corpo”.

Por exemplo, ao processar o fragmento _process, o corpo que serve de critério de busca é E020‑E034.

func _process(delta):
	var velocity = Vector2.ZERO
	if Input.is_action_pressed(&"move_right"):
		velocity.x += 1
	if Input.is_action_pressed(&"move_left"):
		velocity.x -= 1

	if velocity.length() > 0:
		velocity = velocity.normalized() * speed
		$AnimatedSprite2D.play()
	else:
		$AnimatedSprite2D.stop()

	position += velocity * delta
	position = position.clamp(Vector2.ZERO, screen_size)

Neste texto, as pistas que podem ser usadas para pesquisa são apresentadas da seguinte forma.

Input.is_action_pressed
Vector2.ZERO
velocity.normalized
position.clamp
AnimatedSprite2D
_process
Godot 3
Godot 4
migration

Entre as pistas acima, Godot 3, Godot 4 e migration são adicionados quando o prompt do usuário é um pedido como “Verifique se este projeto é Godot 3 ou Godot 4 e, se necessário, encontre a base da conversão”.

A busca Retriever usa o corpo deste fragmento e as pistas.

A busca vetorial inclui o corpo completo da função _process e os principais símbolos.

Na pesquisa por palavras‑chave, são incluídos nomes de símbolos como Input.is_action_pressed, Vector2.ZERO, position.clamp.

O caminho do arquivo player.gd não é usado como termo de pesquisa. No entanto, ele é usado posteriormente para anexar nos logs e na UI a mensagem “Esta pesquisa ocorreu em E020‑E034 de player.gd”.

Etapa 6: O que o Retriever está procurando

O Retriever pesquisa docs_chunks, api_mapping e label_prototypes da mesma forma usando o mesmo fragmento. Nenhuma das três tabelas recebe tratamento especial.

Em docs_chunks podem aparecer candidatos de descrição da documentação oficial, como Input.is_action_pressed, Vector2.ZERO, position, Area2D.

Em api_mapping podem surgir candidatos de nomes de funções, classes e propriedades que foram alterados do Godot 3 para o Godot 4. Por exemplo, se o fragmento de código contiver pistas como KinematicBody2D, yield, Color8, podem ser sugeridas migrações relacionadas.

label_prototypes pode apresentar candidatos como “padrão em que o modo de uso de uma função muda completamente” ou “exemplo em que a composição dos argumentos e a forma de chamada mudam”. Isso tem sentido quando não se trata apenas de uma mudança de nome, mas de explicar a própria forma de uso.

Por exemplo, no fragmento _process, os seguintes candidatos podem ser retornados.

docs_chunks candidato:
  Input.is_action_pressed descrição da documentação oficial
  Vector2.ZERO descrição da documentação oficial
  Node2D.position descrição da documentação oficial

api_mapping candidato:
  Nesta parte pode não haver candidatos de renomeação especiais de Godot 3 -> 4

label_prototypes candidato:
  Exemplo de código de movimento Godot 4 usando Input.is_action_pressed e Vector2.ZERO

Essas candidaturas não são a resposta correta. São apenas “evidências que podem estar relacionadas a este trecho de código”.

Etapa 7: Passar os resultados do Retriever para o LLM

O LLM recebe o prompt do usuário, o trecho de código atual e as candidaturas do Retriever juntos.

Por exemplo, no trecho _process, é inserido da seguinte forma.

**Solicitação do usuário:**  
Verifique se este projeto é Godot 3 ou Godot 4 e, se necessário, encontre a base para a conversão.

**Trecho de código atual:**  
`player.gd` das linhas E020‑E034

func _process(delta):
	var velocity = Vector2.ZERO
	if Input.is_action_pressed(&"move_right"):
		velocity.x += 1
	if Input.is_action_pressed(&"move_left"):
		velocity.x -= 1

	if velocity.length() > 0:
		velocity = velocity.normalized() * speed
		$AnimatedSprite2D.play()
	else:
		$AnimatedSprite2D.stop()

	position += velocity * delta
	position = position.clamp(Vector2.ZERO, screen_size)

**Candidatos de recuperador:**  
- Candidato de documentação oficial para `Input.is_action_pressed` em `docs_chunks`  
- Candidato de documentação oficial para `Vector2.ZERO` em `docs_chunks`  
- Candidato de documentação oficial para `Node2D.position` em `docs_chunks`  
- Exemplo de tratamento de entrada no Godot 4 em `label_prototypes`

LLM aqui determina duas coisas.

Primeiro, verifica se o candidato encontrado está realmente relacionado ao trecho de código atual.

Segundo, decide se o trecho de código atual pertence a um sinal do Godot 3, a um sinal do Godot 4 ou se requer migração.

Neste exemplo, Input.is_action_pressed, Vector2.ZERO e position.clamp podem ser interpretados como evidências de que o código também pode ser usado no Godot 4. Portanto, é provável que esse trecho seja acumulado como “pode ser visto como código Godot 4, sem necessidade de migração”.

Etapa 8: Fluxo do trecho de exemplo do Godot 3

Suponha que exista o seguinte trecho em outro arquivo.

G101 # enemy.gd
G102 extends KinematicBody2D
G103
G104 var velocity = Vector2.ZERO
G105
G106 func _physics_process(delta):
G107 	velocity = move_and_slide(velocity)

enemy.gd é um arquivo .gd, portanto o corpo G102-G107 entra no AST Parser.

O primeiro fragmento é G102.

extends KinematicBody2D

O segundo fragmento é G106‑G107.

func _physics_process(delta):
	velocity = move_and_slide(velocity)

Se você passar o fragmento extends KinematicBody2D para o Retriever, a pista de pesquisa será capturada da seguinte forma.

KinematicBody2D
Godot 3
Godot 4
migration

Neste caso, no api_mapping pode aparecer um candidato de migração de KinematicBody2D para a família CharacterBody2D no Godot 4.

No docs_chunks podem surgir candidatos de documentação oficial sobre CharacterBody2D ou corpos físicos.

No label_prototypes pode aparecer um exemplo de código de movimentação baseado em KinematicBody2D que foi alterado para usar CharacterBody2D com velocity e o método move_and_slide().

No LLM, isso seria inserido da seguinte forma.

**Solicitação do usuário:**  
Verifique se este projeto está usando Godot 3 ou Godot 4 e, se necessário, encontre a base para a migração.

**Trecho de código atual:**  
`enemy.gd` na linha **G102**

extends KinematicBody2D

**Candidatos para recuperação:**  
- **api_mapping:** candidato de migração `KinematicBody2D` → `CharacterBody2D`  
- **docs_chunks:** candidato de documentação oficial `CharacterBody2D`  
- **label_prototypes:** exemplo de conversão de código de movimento `KinematicBody2D`

O LLM pode julgar este fragmento como “Sinal de Godot 3 forte e necessidade de migração”.

Em seguida, o fragmento G106‑G107 também será tratado separadamente.

func _physics_process(delta):
	velocity = move_and_slide(velocity)

Neste fragmento, a forma de chamada move_and_slide(velocity) serve como pista de pesquisa. Não se observa apenas o nome da função, mas também a forma da chamada com seus argumentos.

Nesse caso, se for apenas uma mudança simples no nome da função, o candidato api_mapping é importante, e se a forma completa da chamada mudar, o candidato label_prototypes também se torna relevante.

9º passo: Acúmulo dos resultados dos fragmentos

Cada fragmento é avaliado individualmente.

Os códigos E020‑E034 de player.gd podem ser acumulados como sinais de Godot 4.

O código G102 de enemy.gd pode ser acumulado como sinal de Godot 3.

Os códigos G106‑G107 de enemy.gd também podem ser acumulados como sinais de migração para Godot 3.

A avaliação do projeto como um todo não é feita pelo nome do arquivo. O caminho do arquivo serve apenas para rastreamento. A avaliação geral do projeto resulta do acúmulo das avaliações de cada fragmento de código.

Por exemplo, se em um projeto a maioria dos sinais indica Godot 4, mas alguns sinais de migração para Godot 3 aparecem, a decisão pode ficar próxima de mixed. Por outro lado, se a maioria dos sinais indica migração para Godot 3, o projeto pode ser classificado como um projeto Godot 3.

Interrupção e retomada

RunPod ou um servidor web local podem parar no meio do processo. Portanto, o tratamento deve ser feito por fragmentos, não por arquivos, para que possa ser continuado.

Por exemplo, se foram processados até E009, E011, E013‑E014 de player.gd e o processo parou em E016‑E018, ao reiniciar deve‑se começar novamente a partir de E016‑E018.

Os códigos já concluídos E009, E011, E013‑E014 não devem ser processados novamente.

Na interface web, o seguinte deve ser exibido.

player.gd E009 processamento concluído  
player.gd E011 processamento concluído  
player.gd E013-E014 processamento concluído  
player.gd E016-E018 processamento em andamento interrompido  
player.gd E020-E034 em espera  
player.gd E036-E039 em espera

Assim, pode‑se verificar se “o processamento existente continua ou se reinicia do início”.

O que deve ser exibido na tela de depuração

A tela de depuração é necessária para rastreamento.

Pelo menos o seguinte deve ser exibido.

**Arquivo atual:** player.gd  
**Faixa de linhas atual:** E020-E034  
**Conteúdo do trecho atual:**
func _process(delta):
	...

**Pistas de pesquisa inseridas no Retriever:**  
- Input.is_action_pressed  
- Vector2.ZERO  
- position.clamp  

**Candidatos encontrados:**  
- docs_chunks: Input.is_action_pressed  
- docs_chunks: Vector2.ZERO  
- label_prototypes: Exemplo de polling de entrada no Godot 4  

**Avaliação do LLM:**  
- Sinal do Godot 4  
- Não é necessária migração

O que é importante aqui é que “o que foi incluído na pesquisa” e “o que foi apenas anexado para rastreamento” aparecem separados.

player.gd pode ser exibido na visualização do arquivo atual. No entanto, não deve entrar na lista de pistas de pesquisa do Retriever.

Resumo

A seguir está o fluxo fixado no documento a partir do dia 27.

# <caminho relativo>
<corpo do texto>

-> Divide apenas os limites do arquivo usando cabeçalhos.  
-> O corpo do arquivo .gd é passado para o AST Parser.  
-> O AST Parser corta funções e declarações em ordem.  
-> O corpo real de cada fragmento e a pista de símbolo são inseridos na pesquisa do Retriever.

-> Pesquisar `docs_chunks`, `api_mapping` e `label_prototypes` da mesma forma.  
-> Passar os candidatos de busca e o fragmento atual juntos para o LLM.  
-> Salvar o julgamento do LLM por fragmento e acumulá-lo por projeto.

O objetivo deste documento não é definir uma nova estrutura, mas permitir verificar em que linha a entrada real é cortada e qual conteúdo passa para a próxima etapa. Ao implementar, também deve‑se exibir na interface web, de acordo com este critério, o arquivo atual, o intervalo de linhas atual, o conteúdo realmente transmitido, a pista de busca do Retriever, os candidatos de busca e o julgamento do LLM.