Skip to content

feat(heap-effects): H0 — inert HeapEffectSummary sidecar (extractor facts + Python/Rust solver) - #389

Merged
PhysShell merged 2 commits into
mainfrom
ccr-d3ed89e2-vnl6fk
Oct 3, 2026
Merged

PhysShell merged 2 commits into
mainfrom
ccr-d3ed89e2-vnl6fk

Conversation

@PhysShell

Copy link
Copy Markdown
Owner

Что и зачем

Второй summary-домен рядом с MOS: что метод может сделать с памятью, видимой вызывающему. Это параметры, receiver, записи instance/static/indirect и return alias, где Unknown поглощает. Это фундамент для H1 (Harmless(callee, region-resource) в ProtocolLowering). Срез инертный: ни verdict, ни refusal, ни диагностика его не читают.

  • Экстрактор: --heap-effects FILE пишет source facts в отдельный файл уже после того, как facts готовы (HeapEffectFacts.cs). Это default-deny IOperation-walk; он ничего не решает.
  • Ядро: решатель ownlang/heap_effects.py (reference, python -m ownlang.heap_effects) и own-bridge/src/heap_effects.rs (own_bridge::dump_heap_effects). Least fixpoint по SCC-конденсации; эффекты plain < borrow < borrow_mut < may_escape < unknown, записи none < may < unknown.
  • Вне scope и не тронуто: OwnIR version, ProtocolLowering, семантика P-037, T0/perf, существующие диагностики, публичный CLI python -m ownlang. Единственная правка существующего Rust-кода: dump.rs::emit стал pub(crate).
  • Регенерировано: docs/generated/p022-coord-census.md. Census теперь считает и line-слоты новой fixture-семьи.

Подробности: docs/notes/heap-effect-summaries.md. Предыдущий kill-first: docs/notes/protocol-harmless-call-summary-gap.md.

Тип изменения

  • feat — новая возможность
  • fix — исправление бага
  • docs — документация
  • refactor / chore / test / ci — без изменения поведения (новый CI-шаг в state-protocols)

Как проверено

  • python tests/run_tests.py (rc=0 на чистом дереве)
  • ruff check . и mypy
  • cargo fmt --check, cargo clippy --all-targets (новых предупреждений нет), cargo test
  • python scripts/protocol_gate.py --rust …/own-cli: 0 failures, 19 документов байт-в-байт на обоих CLI
  • python scripts/heap_effects_gate.py: sidecar сэмплов воспроизводится; 38 прогонов с флагом и без дают идентичные facts-байты, exit code и stderr
  • Паритет Python/Rust: 10 golden-кейсов и 16 текстов rejection байт-в-байт (tests/test_heap_effects_fixtures.py, own-bridge/tests/heap_effects.rs). Дифференциальный фазз на 4000 случайных sidecar'ов (1318 rejection): расхождений 0. Три подсаженных мутанта ловятся и goldens, и фаззом.
  • Регрессия против main (a27a827): экстрактор main против этой ветки без флага, 208 C#-входов плюс 4 сканирования директорий × 3 режима флагов. 220/220 совпадают по facts-байтам, exit code и stderr, включая 2 refusal.

Связанные issue

Refs P-036 / P-037. Отдельного issue нет.

Чеклист

  • изменение покрыто тестом/селфтестом (или объяснено, почему нет)
  • README/docs обновлены при необходимости
  • коммиты в conventional-commit стиле (feat:, fix:, docs: …)

🤖 Generated with Claude Code

https://claude.ai/code/session_011ZFvhLx1fM9Gerg4dKsZcL


Generated by Claude Code

claude added 2 commits October 3, 2026 13:31
…is missing

Kill-first finding at main a27a827: the only solved summary (MOS / P-037
guarded transfer) cannot prove a call harmless inside a protocol region.
Non-disposable methods get no record, borrow_mut collapses into borrow, and
the escapes axis has no producer, so a writer and an escaper both solve to
transfer=no. Deferring the decision to the core needs a must-understand
OwnIR construct (IR3/IR4), i.e. a version bump.

Records the missing contract (HeapEffectSummary -> Harmless(callee)) and
proposes H0 (inert heap-effect summary domain, facts-only sidecar, no
verdict change) and H1 (the wire, pending an owner ruling on OwnIR).
No code, fixture, freeze or verdict changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ZFvhLx1fM9Gerg4dKsZcL
…acts + Python/Rust solver)

A second summary domain beside MOS, produced and solved end to end and read
by nothing that decides a verdict or a refusal.

- Extractor: `--heap-effects FILE` writes heap-effect SOURCE FACTS to a
  separate file after the facts document is final (HeapEffectFacts.cs).
  Default-deny IOperation walk: sources, derefs, writes, stores, returns,
  calls (callee/dispatch/args), locals, unknown reasons. No solving.
- Core: ownlang/heap_effects.py (reference, `python -m ownlang.heap_effects`)
  and own-bridge heap_effects.rs (`own_bridge::dump_heap_effects`): least
  fixpoint over the SCC condensation; effects plain < borrow < borrow_mut <
  may_escape < unknown, writes {instance,static,indirect} none < may <
  unknown, return aliases; Unknown absorbs.
- Parity: tests/fixtures/heap_effects (10 cases, 16 rejection texts),
  byte-exact on both engines; 30 pinned kill-fixture summaries.
- Inertness: scripts/heap_effects_gate.py (CI state-protocols job) proves the
  facts bytes, exit code and stderr do not move with the flag.
- No OwnIR version, verdict, ProtocolLowering, P-037 or diagnostic change.
  The p022 coordinate census is regenerated for the new fixture family.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ZFvhLx1fM9Gerg4dKsZcL
@PhysShell
PhysShell merged commit 1c70e86 into main Oct 3, 2026
78 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants