Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
1b75d53
Fix imported abstract interfaces and callback scalar outputs
saidctb Sep 14, 2026
195e32b
Treat an undeclared callback scalar intent as conservatively writable
saidctb Sep 14, 2026
85c5893
Prove the undeclared callback intent through a contract round trip
saidctb Sep 15, 2026
ec7002a
Resolve imported callback interfaces in their declaring module
saidctb Sep 15, 2026
b0364b8
Carry interface provenance through results, renames, and accessibility
saidctb Sep 15, 2026
9623e8c
Spell runtime extents the way a contract spells them in diagnostics
saidctb Sep 15, 2026
e0f9a19
Extract prototype binding from external reference reconciliation
saidctb Sep 15, 2026
eed7e66
Remove the Strided contract name and the dimension step
saidctb Sep 15, 2026
d362f6d
Carry a strided axis as the spelling a contract uses
saidctb Sep 15, 2026
0b9d450
Record the declaring name for a renamed re-export chain
saidctb Sep 15, 2026
f0b3c14
Build one generic interface from every block that declares it
saidctb Sep 15, 2026
ac314f3
Extend a generic interface across the modules that build it
saidctb Sep 15, 2026
dfd955f
Publish an imported procedure a module explicitly makes public
saidctb Sep 15, 2026
841575d
codex: generate relative sibling imports in Fortran leaf contracts
saidctb Sep 15, 2026
2a1dd8f
Keep native scopes bare under relative sibling imports
saidctb Sep 15, 2026
51de26f
Keep every import when a scope uses one module repeatedly
saidctb Sep 15, 2026
bf935a6
Remove an empty test module left by a probe
saidctb Sep 15, 2026
0a040df
Collect every specific a split generic binding names
saidctb Sep 15, 2026
3f7955a
Resolve a kind an interface body names for itself
saidctb Sep 15, 2026
586e4e6
Accept an overload declaration that restates a projected result
saidctb Sep 15, 2026
6ec888d
Import each name as the contract defining it spells it
saidctb Sep 15, 2026
6f439d3
Let a contract rename the entity a declaration reaches
saidctb Sep 15, 2026
fc4a32d
Record a source spelling only where Python cannot hold the name
saidctb Sep 15, 2026
08722d9
Re-export a published name only where Python holds one object
saidctb Sep 15, 2026
349ea0d
Follow a published name to its declaration, and publish only what a c…
saidctb Sep 16, 2026
8b9fc7f
State what a contract publishes in its own __all__
saidctb Sep 16, 2026
8c64482
Let a stated __all__ name a package's sub-namespaces too
saidctb Sep 16, 2026
c787c84
Own a re-export by its declaring contract, not by traversal order
saidctb Sep 16, 2026
63648fa
Say that a C export allowlist states the same surface as __all__
saidctb Sep 16, 2026
bda1c03
Say where a direct C build writes its stubs
saidctb Sep 16, 2026
80aef84
Decide a public name once, and let every stage write that one
saidctb Sep 16, 2026
c8771d5
Name the defect where one decision gets derived twice
saidctb Sep 16, 2026
664c48e
Decide a public name once, and let every stage write that one
saidctb Sep 16, 2026
773f095
codex: preserve module variable reexports
saidctb Sep 16, 2026
b35ce84
Carry the bundled helpers a namespace alias binds through
saidctb Sep 16, 2026
54e73a6
Own a re-exported variable without publishing where it is declared
saidctb Sep 16, 2026
b62216f
Name the bspline classes the way the wrapper now publishes them
saidctb Sep 16, 2026
c67df02
Let the installed environment import what the wheel depends on
saidctb Sep 16, 2026
9493296
Record a published name the way its source spells it
saidctb Sep 16, 2026
b232a0a
codex: stabilize reexports and variable ownership
saidctb Sep 17, 2026
e98c87b
codex: preserve TA-Lib reference inputs
saidctb Sep 17, 2026
338c973
codex: separate Fortran accessibility from Python exports
saidctb Sep 17, 2026
d748891
Judge a callback and an abstract interface by the same accessibility
saidctb Sep 17, 2026
d43b6de
Read a declaration's references rather than scan its text
saidctb Sep 17, 2026
5dd3a27
Accept a raw address extent built from a supported call
saidctb Sep 17, 2026
3cc89a2
Give each procedure the interfaces it declares, and read selectors as…
saidctb Sep 17, 2026
a763b31
Leave a character literal's contents out of lexical translation
saidctb Sep 17, 2026
db494aa
Carry a character selector's length apart from its kind
saidctb Sep 17, 2026
5301f35
Read a Fortran character literal rather than hand it to Python
saidctb Sep 17, 2026
dbb45b5
Read a character declaration's kind as the selector separates it
saidctb Sep 17, 2026
9ea35dc
Specialize declaration expressions, not every metadata string
saidctb Sep 17, 2026
70bf45c
Give a character model one recorder for its selector
saidctb Sep 17, 2026
31936b1
Accept a character literal that states its kind
saidctb Sep 17, 2026
33364ea
Read a character kind from the selector before the legacy field
saidctb Sep 17, 2026
e717f0b
Rename argument references without reaching inside literals
saidctb Sep 17, 2026
c2b4770
Break a continued Fortran line at the expression's own commas
saidctb Sep 17, 2026
f626c32
Publish a prototype or generic only where the module declares it
saidctb Sep 17, 2026
79f3504
Decide a generic re-export's publication where publication is decided
saidctb Sep 17, 2026
aabd16d
Apply the same resolution rule at every re-export hop
saidctb Sep 17, 2026
c0561ac
Carry an enum's enumerators as the constants they already are
saidctb Sep 17, 2026
31f8262
Weigh every route to a name, however each one entered
saidctb Sep 18, 2026
9cbe581
Assemble a generic from every interface contributing to it
saidctb Sep 18, 2026
95c3ca1
Identify a prototype by its scope, and allocate its spelling once
saidctb Sep 18, 2026
e713692
Let a contract's __all__ decide what reloading it publishes
saidctb Sep 18, 2026
45b0586
Record whether a use statement narrowed to an only list
saidctb Sep 18, 2026
78f3ee3
Identify a generic's specific by the module declaring it
saidctb Sep 18, 2026
812c934
Hold the names a module imports while naming its prototypes
saidctb Sep 18, 2026
8201022
Read a stated export surface exactly, and an empty one as stated
saidctb Sep 18, 2026
57425d2
Bind a generic's private specifics in one place
saidctb Sep 18, 2026
3307548
Keep each use statement, and read them in one place
saidctb Sep 18, 2026
112de90
Finish structural identity for a generic's specifics
saidctb Sep 18, 2026
334ecca
Hold a fix to removing an interpretation path
saidctb Sep 18, 2026
e35c976
Read one scope's use statements through one resolver
saidctb Sep 18, 2026
745228e
codex: finish scope use resolution
saidctb Sep 18, 2026
ffc26ca
Complete contract spelling once, before emission
saidctb Sep 18, 2026
1430faa
Decide every export, and define a type whether or not it is published
saidctb Sep 19, 2026
50e1ed0
Plan a contract's imports once, from what it needs to bind
saidctb Sep 19, 2026
7fbd8aa
Spell each imported name one way throughout its contract
saidctb Sep 19, 2026
0027bd2
Spell a declaration-expression call the way the contract binds its ca…
saidctb Sep 19, 2026
62e9d75
Show the generated contract from the parser CLI's --pyi
saidctb Sep 19, 2026
7f4cdae
State @pure on a pure module function in its contract
saidctb Sep 19, 2026
a2e4f7d
Check an actual against the extent a specification function declares
saidctb Sep 19, 2026
1b26c74
Skip the whole call on an extent mismatch, not only the native procedure
saidctb Sep 19, 2026
efb733e
Plan each bridge-evaluated extent once, and pin the rejection boundary
saidctb Sep 19, 2026
2798cb2
Spell prototypes in the contract ledger, not while converting source
saidctb Sep 19, 2026
8f59493
Let a generic own its export decision
saidctb Sep 19, 2026
16d6c23
Remove the retired Boolean-array copy
saidctb Sep 19, 2026
677e2f6
Reach each type in the namespace defining it, by its backend symbol
saidctb Sep 19, 2026
af51ffa
Let a type extend one another module declares
saidctb Sep 19, 2026
1886b13
codex: finish derived type contract naming
saidctb Sep 19, 2026
d347264
codex: link variable publications to their owner plan
saidctb Sep 20, 2026
ea729f8
codex: keep edited variable plan graphs coherent
saidctb Sep 20, 2026
8e89564
codex: isolate the direct C contract module name
saidctb Sep 20, 2026
c92462b
codex: preserve optional callback presence
saidctb Sep 20, 2026
fdf4f2b
codex: validate callback presence plans
saidctb Sep 20, 2026
96f78f8
codex: omit direct callback bridge adapters
saidctb Sep 20, 2026
0d85d5d
codex: Define concise test fixture rules
saidctb Sep 20, 2026
7dc4800
codex: Move callback projects into fixtures
saidctb Sep 20, 2026
f099b96
codex: Move array projects into fixtures
saidctb Sep 20, 2026
350ae85
codex: Move module projects into fixtures
saidctb Sep 20, 2026
7043bad
codex: Move derived type projects into fixtures
saidctb Sep 20, 2026
a540e42
codex: Move allocatable projects into fixtures
saidctb Sep 20, 2026
c0e8959
codex: Move pointer projects into fixtures
saidctb Sep 20, 2026
8a594c2
codex: Move string projects into fixtures
saidctb Sep 20, 2026
c7b4bc3
codex: Move scalar and generic projects into fixtures
saidctb Sep 20, 2026
a516d09
codex: Move substantial stage inputs into fixtures
saidctb Sep 20, 2026
28c0cea
codex: Move fixed integration sources into fixtures
saidctb Sep 20, 2026
8f2446e
codex: Reuse shared Fortran fixtures
saidctb Sep 20, 2026
5f39256
codex: Finish substantial Fortran fixture extraction
saidctb Sep 20, 2026
4720f10
codex: Consolidate USE accessibility matrices
saidctb Sep 20, 2026
33a267c
codex: Document stage-local native fixtures
saidctb Sep 20, 2026
02e0649
codex: Finish fixed Fortran fixture migration
saidctb Sep 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
101 changes: 101 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,50 @@ rewrite the test when that invariant remains a contract; remove it when it only
records the previous implementation or a recommendation. Do not change correct
behavior solely to satisfy a brittle test.

Before adding a test, name the invariant, its feature or infrastructure owner,
and the earliest stage that can prove it. Keep the resulting evidence concise:

- One test may assert several related consequences of the same setup and
invariant. Do not create one test function per field or incidental detail.
- Use parametrization when cases exercise the same operation and assertion
shape with different inputs, and give every row a descriptive ID.
- Do not repeat the same invariant at adjacent stages. Add another stage test
only when it protects a real handoff, completed decision, generated artifact,
ABI mechanism, or runtime behavior.
- Cover combinatorial language cases at the cheapest owning stage. End-to-end
tests should cover each distinct compilation, ABI, ownership, lifetime, or
runtime mechanism, not every combination already established below it.
- When source and generated-contract builds must agree, compare the two lanes
in one test or shared case instead of maintaining unrelated duplicate tests.
- When several tests use the same native project and require no isolated build
state, build it once through an appropriately scoped pytest fixture. Do not
share mutable native state unless the fixture resets it deterministically.
- Prefer existing test helpers. Add a shared helper only when it removes
repeated setup from multiple tests without hiding the behavior being tested.
- Do not duplicate a complete expected artifact in several tests. Keep one
reviewed golden or fixture as its authority and make focused tests assert
only the relevant property.
- Do not assert complete generated source text when a focused structural or
behavioral assertion proves the invariant, unless the generated text is
itself a documented serialized format.
- When removing or consolidating a test, identify the invariant it protected
and show where that invariant remains covered.

Organize native test sources by their evidence owner:

- A permanent source compiled by a test belongs in a fixture file.
- A multi-file native project uses one fixture file per real source file.
- A source shared by tests, or a substantial source of roughly 20 lines or
more, should normally be a fixture file.
- A small syntax example should remain inline when locality makes the test
clearer.
- Programmatically generated, parametrized, or deliberately mutated source may
remain inline and must be written only to pytest temporary directories.
- Place fixtures beneath the feature or infrastructure mechanism that owns the
asserted behavior and beneath the relevant stage. Do not place
feature-specific sources in `_support` or create a global collection of
unrelated fixtures.

The agent owns the review work that is not delegated to rigid tests. Before and
after a refactor, compare the affected public behavior and stage outputs. When
editing documentation, examples, diagnostics, or generated text, preserve the
Expand Down Expand Up @@ -98,6 +142,63 @@ the selected plan requires a genuinely new emitted-code mechanism; those
generators should otherwise keep reusing and dispatching existing planned
paths.

A decision is read, not recomputed. Completed policy moving forward also means a
later stage must not derive the same answer a second time, which is harder to
notice than an override because the second site often calls the same helper and
so reads as reuse rather than as a second authority. When two places need one
answer, ask: **if these two call sites disagreed, which one would be wrong?** If
that has no answer, the decision has two authorities and no owner; if it has
one, the other site must read the answer rather than compute it. This applies to
derivation carrying state or a condition — a collision counter, a reservation
ledger, a language gate, a default — because that is what drifts; calling a
pure, total helper from several stages is fine. Read the owner's recorded
output: the completed policy, the shared plan, or the metadata the owner wrote.
Where a stage cannot run the owner's full completion, run the narrower
completion step for that one decision rather than deriving it again — contract
extraction must describe C that the direct-only wrapper would reject, so
`emit_module_stubs` completes public-name policy for every module and the rest
only where a build request allows it. Sharing the owner's helper is not enough
when the derivation keeps a ledger: two allocators fed the same declarations in
a different order produce the same set of names attached to different
declarations, which every per-stage test still passes.

A fix removes an interpretation path or it does not land. "The regression is
fixed and the tests pass" is half an answer; the other half is **did this delete
a way of deciding, or add one?** A representation that has to mean several
things is the usual source of these bugs, and widening it with another flag or
another fallback leaves every existing reader intact and adds a reader. So when
a record cannot express a case, replace the record; when a lookup is reached by
two key shapes, finish the migration to one; when a completed decision is
ambiguous with an absent one, make completion record it; when a consumer
special-cases what a plan should have decided, move the decision into the plan.
Introducing a record, a small class, or a named reading is the preferred move
when it lets a reader see the rule in one place, and it does not need a separate
mandate: reach for it whenever it fixes the bug in fewer lines than another
branch would, and change an existing structure freely when replacing it is what
makes the code read more simply. Prefer that to a new condition threaded through
existing paths, which each reader then has to hold in mind. The one condition is
that the new thing is accepted only if it deletes the branches and helpers it
replaces — moving them to another module, or wrapping them behind a new name,
does not count. The practical test before committing: the file you changed
should be no harder to read than before, and the count of places that answer
your question should have gone down.

Keep the regressions while doing it. The tests that pin bare, `only`, renamed
and repeated `use` forms, route accessibility, transitive re-exports, merged
generics, prototype collisions, exact `__all__`, and source-build versus
generated-`.pyi` replay are the specification of what PRIK supports; simplify
what sits under them, never by dropping the cases they cover.

Where one decision reaches users through two artifacts, a test must compare
those artifacts rather than only check each one. A built extension and the
`.pyi` contract describing it are one such pair: each had passing tests while
the names they published disagreed, because nothing asserted that they agreed.
Treat the same comparison as a recommendation, not a requirement, for internal
pairs such as a wrapper plan and the sources generated from it. Watch for a
second policy or allocator instance, for a language, route, or flag gate at the
consumer that the owner lacks, and for a `prik/printers/` helper that returns a
name, kind, or decision rather than text.

To answer an ABI question, or to decide whether something belongs in the
binding or in the Fortran bridge, first ask: **how would this work for a
`bind(C)` procedure, where there is no bridge at all?** A direct entrypoint has
Expand Down
Loading
Loading