This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Experimento meio filosófico, meio de programação: uma "Matrix" de brinquedo no terminal (ASCII) onde blocos-agentes sobem uma escada de senciência (níveis 0–6: reatividade → memória → valência → modelo de mundo → agência → auto-modelo → aprendizado/seleção natural). Tudo em um único arquivo C (main.c), só libc, sem dependências.
README.mdé o como (arquitetura, parâmetros, efeitos medidos) — mantê-lo em dia faz parte de qualquer mudança de comportamento.FILOSOFIA.mdeFILOSOFIA_v2.mdsão o porquê (o manifesto; a bateria de desbotamento). Docs e UI em pt-BR; código e commits sem acentos.ROADMAP.mdé o para onde: os eixos de pesquisa, os riscos de cada um, e o que o projeto escolhe não ser (paralelização/SIMD quebram o determinismo; um arquivo por experimento quebra a comparabilidade dos datasets).datasets/guarda CSVs congelados com manifesto de proveniência (comando + commit demain.c, emdatasets/README.md);datasets/gerar.shregenera tudo. Após mudança de comportamento intencional, regenerar e atualizar o manifesto.notebooks/analisa os datasets (commitar sem outputs);papers/é a escrita formal (fonte + PDF);viz/é a camada de visualização aditiva que gera as figuras dos papers a partir dedatasets/*.csv(viz/README.md) — só leitura, nunca tocamain.c.
Não há Makefile neste repo (o make matrix do README vem do repo maior c_training/ de onde o projeto foi extraído). Compilação direta, verificada limpa com:
gcc -std=c11 -Wall -Wextra -O2 -o matrix main.cNunca adicione <math.h>/-lm — o projeto compila sem -lm de propósito; o ruído usa aritmética inteira e o resto polinômios.
./matrix [seed] [ticks] [delay_ms] [foco] # defaults: 20260628, 0 (infinito), 80, -1 (visão de deus)
./matrix 7 2000 0 --log run7.csv # headless, gera CSV (1 linha de stats/tick)A animação exige terminal de verdade (≥ ~70 colunas; ANSI). Teclas: p/TAB primeira pessoa, , . troca bloco, espaço pausa, q sai.
O teste do projeto é o determinismo: o universo inteiro é f(seed) — mesma seed ⇒ simulação e CSV bit-a-bit idênticos. Para verificar uma mudança:
./matrix 7 200 0 | grep -a -o 'pop [0-9]*' | tail -1 # checagem rápida de população
./matrix 7 2000 0 --log antes.csv # antes × depois: diff dos CSVsMudanças que não deveriam alterar comportamento devem produzir CSV idêntico. Mudanças de comportamento seguem a cultura do projeto: medir o efeito (A/B com algumas seeds, ex.: parâmetro em 0 vs default) e documentar o achado no README, como feito para ANTECIPACAO e a evolução dos traços.
Pipeline em 4 partes (marcadores PART n no arquivo; main em ~linha 1041):
| Parte | Onde | Papel |
|---|---|---|
| PART 1 — Mundo procedural | ~175 | mundo é f(seed,x,y): hash → value-noise → manchas de comida (gerar_mundo, ruido, hash2) |
| PART 2 — Blocos / cognição | ~257 | a "mente": prever_valor (nv3), utilidade (nv4), declarar/pretendentes_em (nv5), traços herdados com mutação (nv6) |
| PART 3 — Simulação (o tick) | ~413 | fases: declarar → decidir → resolver → aplicar_e_comer → reproduzir → rebrotar |
| PART 4 — Render + laço | ~552 | buffer ASCII + HUD, teclado cru (termios), bateria de desbotamento, log CSV |
Quase toda evolução do projeto mexe só na PART 2 (cognição) ou na reprodução; mundo, tick e render ficam de pé.
- Determinismo total: geração do mundo E decisões/nascimentos usam o mesmo RNG semeado (
rng_estado). Nada detime(),rand()sem seed, ou ordem dependente de ponteiros — quebraria a reprodutibilidade bit-a-bit dos CSVs. - Leitura × escrita separadas no tick: todos decidem lendo o estado estável (preenchendo
alvo_x/alvo_y), só depois o mundo aplica. As duas passagens do nível 5 (intencao_*→alvo_*) usam arrays separados. Misturar as fases reintroduz a "física fantasma" da ordem de varredura (bloco que anda mais rápido só porque o laço o visita antes). - Resolução de conflito (
resolver): só se move para célula vazia no início do tick; célula disputada vai para o pretendente de menor índice, os demais ficam parados. Simplicidade proposital — evita bugs de troca de lugar. - Estado em globais file-static:
comida[][],capacidade[][],ocup[][](índice do bloco ou -1),blocos[].vivo == 0marca slot livre;alocar_slot()reaproveita o buraco de menor índice antes de estendern_blocos(não reaproveitar impunha um teto de ~1348 nascimentos por simulação e congelava a evolução por volta do tick 10 000). Comoresolver()desempata pelo menor índice, o índice não é neutro: no código antigo ele codificava a ordem de nascimento, e o mais velho vencia toda disputa. - Percepção estritamente local (vizinhança 3×3): nenhum bloco lê estado global — o comportamento global deve emergir.
- As "leis da física" são os
#defineno topo do arquivo;HORIZONTE,DESCONTO,URGENCIA,PESO_ESPACOsão apenas médias iniciais — os valores reais são traços por bloco (nível 6), herdados com mutação.
Os mostradores (modelo, agencia, modelo_do_outro, phi, relato, autocausa), todos em [0,1], medem se uma faculdade carrega o comportamento (famílias: ablação e calibração) — função, nunca experiência. Aparecem no HUD e no CSV (--log). Colunas do CSV: seed, tick, pop, energia_media, comida_total, média e desvio dos 4 traços (*_m, *_sd), os mostradores, hon_f/blef_f (fração da população por estratégia de sinalização — o relato causal, Fase 4) e, no fim, autocausa. Coluna nova entra no FIM — assim as anteriores seguem compatíveis por prefixo com os CSVs antigos, e um cut -d, -f1-N vira teste de regressão. Ao adicionar/renomear coluna, manter a reprodutibilidade e atualizar o README (e o notebook, que lê colunas por nome). (modelo_do_outro era automodelo — renomeado na nota 04: mede o outro, não o self. phi foi redefinida na nota 05. relato foi pré-registrado no ROADMAP §2.0 antes de ser construído — nota 06. autocausa foi pré-registrado no §5.0 — nota 09: é o único mostrador que não zera no eremita, e mede o self como causa (food -= garfada, em prever_valor); horizonte = 1 o zera exato.)
A régua roda em float32, e isso tem um piso (nota 09 §5): a agencia do eremita, que a nota 01 provou ser "0 exato", vaza ~0,003 por arredondamento (some em double). Ao afirmar que uma ablação zera um mostrador, recompute a comparação em double antes de escrever ✅ — a demonstração algébrica não basta.
Estilo do histórico: matrix: <descrição em pt-BR sem acentos>, uma mudança conceitual por commit (um degrau da escada, um mostrador, uma seção de filosofia).