Skip to content

Guard existing module prompt contracts#862

Merged
gltanaka merged 2 commits intomainfrom
fix/issue-798-prompt-contract
May 8, 2026
Merged

Guard existing module prompt contracts#862
gltanaka merged 2 commits intomainfrom
fix/issue-798-prompt-contract

Conversation

@gltanaka
Copy link
Copy Markdown
Contributor

@gltanaka gltanaka commented May 8, 2026

Summary

  • Add a generation-time prompt contract preflight for existing modules whose prompt declares a broad public interface while only including a selected slice of the existing output source.
  • Update the issue complexity and prompt-generation prompts so future splits are independently shippable/verifiable and existing-module prompt context stays aligned with declared interfaces.
  • Switch agentic_common_python.prompt to include the full existing pdd/agentic_common.py source so declared exports are preserved.

Context

This addresses the #798-style failure mode where pdd sync can correctly fail architecture conformance after the generated code drops symbols declared in <pdd-interface> / architecture.json, because the LLM only saw partial existing source context.

Test Plan

  • git diff --check
  • pytest -q tests/test_prompt_contract_validation.py tests/test_agentic_arch_complexity_prompt.py tests/test_architecture_include_validation.py tests/test_code_generator_main.py tests/test_agentic_sync.py
  • pytest -q tests/test_sync_main.py -k "code_generator_main or front_matter or processes_real_language or skips_llm_only or accepts_bracket_basename"
  • pytest -q tests/test_e2e_issue_553_circular_includes_non_recursive.py::TestIssue553CircularIncludesNonRecursiveE2E::test_non_circular_includes_still_work tests/test_e2e_issue_553_circular_includes_non_recursive.py::TestIssue553CircularIncludesNonRecursiveE2E::test_three_file_cycle_default_mode
  • python -m py_compile pdd/architecture_include_validation.py pdd/code_generator_main.py
  • Direct agentic_common prompt contract check: agentic_common prompt contract errors: 0

I also attempted full make test; it reached 99% with no failures shown and included the prior circular-include tests passing, but pytest/xdist hung during teardown on inherited test-helper pipes. I terminated the stuck process group and reran the bounded acceptance suite above successfully.

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@gltanaka
Copy link
Copy Markdown
Contributor Author

gltanaka commented May 8, 2026

I would not merge this yet. The new preflight is pointed at the right failure mode, but it does not currently match the include grammar that generation actually accepts. Needed changes:

  1. Parse the full <include> grammar used by preprocess: body form, path= attribute precedence, and self-closing <include path="..." />. Right now _extract_include_references() only matches <include ...>body</include> and always treats the body as the path, so a partial self-include like <include select="def:keep_me" path="pkg/mod.py" /> bypasses the guard and returns no contract error even when another declared existing symbol is missing. Please add regression tests for self-closing and body-form path= includes.

  2. Fix partial include coverage for non-select forms. _IncludeReference.is_partial treats lines= and query= as partial, but _symbols_covered_by_selectors() only reads select=, so a deterministic line-range self-include can fail with 0 covered symbols even when the line range contains every declared symbol. Either map lines= ranges to covered symbols or handle unsupported partial mechanisms explicitly with clear behavior and tests.

  3. Treat mode="interface" as non-full source context, or document/test why it is allowed. As written, <include mode="interface">pkg/mod.py</include> passes as a full self-include even though preprocessing strips implementation bodies, which leaves the same preservation gap this preflight is meant to catch.

Verification I ran: git diff --check origin/main...HEAD, python -m py_compile pdd/architecture_include_validation.py pdd/code_generator_main.py, pytest -q tests/test_prompt_contract_validation.py, and pytest -q tests/test_agentic_arch_complexity_prompt.py tests/test_architecture_include_validation.py all pass. The blockers above came from an ad hoc contract repro against validate_prompt_contract_context().

@gltanaka
Copy link
Copy Markdown
Contributor Author

gltanaka commented May 8, 2026

Addressed the review blockers in 62f011c. The substantive points were legit:\n\n- Include parsing now matches preprocess for body includes, path= precedence, and self-closing path= includes.\n- Deterministic line-range self-includes now map selected ranges to public symbol spans, including select="lines:...".\n- query-only self-includes and mode="interface" self-includes now fail with explicit unsupported-context reasons instead of being treated as full implementation context.\n\nValidation run locally:\n- git diff --check\n- python -m py_compile pdd/architecture_include_validation.py pdd/code_generator_main.py\n- pytest -q tests/test_prompt_contract_validation.py tests/test_architecture_include_validation.py tests/test_agentic_arch_complexity_prompt.py\n- pytest -q tests/test_code_generator_main.py tests/test_agentic_sync.py\n- pytest -q tests/test_sync_main.py -k "code_generator_main or front_matter or processes_real_language or skips_llm_only or accepts_bracket_basename"\n- pytest -q tests/test_e2e_issue_553_circular_includes_non_recursive.py::TestIssue553CircularIncludesNonRecursiveE2E::test_non_circular_includes_still_work tests/test_e2e_issue_553_circular_includes_non_recursive.py::TestIssue553CircularIncludesNonRecursiveE2E::test_three_file_cycle_default_mode\n\nGitHub checks are green: CodeQL, Package Preprocess Smoke, Public CLI Regression, and Run Unit Tests.

@gltanaka gltanaka merged commit 9b65749 into main May 8, 2026
7 checks passed
@gltanaka gltanaka deleted the fix/issue-798-prompt-contract branch May 8, 2026 18:49
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.

1 participant