Skip to content

Conversation

@Enfoirer
Copy link
Contributor

@Enfoirer Enfoirer commented Jan 12, 2026

Description

Fixes the example import issue with template where LLM generates invalid <include> tags referencing non-existent files, and sync ignores filepath field in architecture.json.

Fixes #225


Changes Made

Bug 1: Invalid <include> Tags in Generated Prompts

Problem: When using generic/generate_prompt template, LLM generates <include> tags like:

<include>[File not found: context/pydantic_example.py]</include>

Code Changes

  • pdd/validate_prompt_includes.py: New module that detects and cleans invalid <include> tags
  • pdd/code_generator_main.py: Integrate validation into generation pipeline - validates .prompt files before saving
  • pdd/templates/generic/generate_prompt.prompt: Update template to instruct LLM NOT to assume files exist

Test Changes

  • tests/test_generate_prompt_template.py: Tests that template should NOT instruct LLM to assume files exist
  • tests/test_validate_prompt_includes.py: Unit tests for the validation module
  • context/validate_prompt_includes_example.py: Usage examples following pdd convention

Prompt Changes

  • pdd/prompts/validate_prompt_includes_python.prompt: New prompt for the validation module
  • pdd/prompts/code_generator_main_python.prompt: Updated via pdd update - added validate_prompt_includes example and documented validation step

Bug 2: pdd sync Ignores architecture.json filepath

Problem: When architecture.json specifies:

{"filename": "models_findings_Python.prompt", "filepath": "src/backend/models/findings.py"}

sync ignores filepath and uses .pddrc defaults, generating files at wrong paths like src/findings.py.

Code Changes

  • pdd/sync_determine_operation.py:
    • _find_architecture_json(): Search upward from CWD to find architecture.json
    • _get_filepath_from_architecture(): Extract filepath for a prompt filename
    • Modified get_pdd_file_paths(): Check architecture.json FIRST before .pddrc

Test Changes

  • tests/test_sync_determine_operation.py: Added 4 test classes with 11 tests:
    • TestSyncArchitecturePaths: Basic architecture.json filepath extraction
    • TestSyncArchitecturePathIntegration: Integration tests
    • TestArchitectureJsonLookup: Discovery and module matching
    • TestGetPddFilePathsWithArchitecture: Function behavior verification

Prompt Changes

  • pdd/prompts/sync_determine_operation_python.prompt: Updated via pdd update - documented path resolution priority order

Path Resolution Priority (Issue #225)

  1. User-specified output path (command line)
  2. architecture.json filepath field ← NEW
  3. .pddrc outputs config (template-based paths)
  4. .pddrc generate_output_path config
  5. Default naming conventions

Testing

Test Results

======================== 89 passed in 2.47s ========================
(test_sync_determine_operation.py)

======================== 37 passed in 2.50s ========================
(Issue #225 specific tests)

Coverage

Module Coverage
sync_determine_operation.py 76%
validate_prompt_includes.py 92%
Bug fix code 100%

Testing Environment

  • Platform: macOS Darwin 24.6.0
  • Python: 3.13.7

Prompt Generation Verification

Verified that validate_prompt_includes_python.prompt can generate functionally equivalent code:

  • pdd generate succeeds
  • ✅ Generated code imports correctly
  • ✅ Core functions work as expected

Dev Unit Checklist

  • Code: Updated implementation for both bugs
  • Tests: Added comprehensive test coverage (PDD approach - tests first, then fix)
  • Prompt: Synced via pdd update for both modified modules
  • Example: Added validate_prompt_includes_example.py

Regression Testing

  • All existing tests pass
  • No changes to public API
  • Backward compatible with existing .pddrc configurations

Commit Structure (PDD)

  1. Add failing tests to reproduce Issue Example import issue with template #225 Bug 1
  2. Fix Issue Example import issue with template #225 Bug 1 (code + prompt)
  3. Add failing tests to reproduce Issue Example import issue with template #225 Bug 2
  4. Fix Issue Example import issue with template #225 Bug 2 (code + prompt)

Related Issues


Additional Notes

This fix follows PDD principles:

  • PDD approach: Failing tests committed before fixes
  • Prompts synced: Both code_generator_main and sync_determine_operation prompts updated to reflect new functionality
  • Code regeneration safe: Regenerating from updated prompts will preserve this fix

Frostday and others added 21 commits January 2, 2026 11:30
…-detection

Fix/windows uv path detection
…<include> tags

Problem: LLM generates <include> tags referencing non-existent files like:
  <include>[File not found: context/pydantic_example.py]</include>

Tests added:
- test_generate_prompt_template.py: Tests that template should NOT instruct
  LLM to assume files exist, and should provide alternatives for missing deps
- test_validate_prompt_includes.py: Unit tests for the validation module
- context/validate_prompt_includes_example.py: Usage examples for the
  validation module (following pdd's module-example convention)
…> tags

Solution:
1. pdd/validate_prompt_includes.py: New module that detects and cleans
   invalid <include> tags like "[File not found: ...]" from generated prompts

2. pdd/code_generator_main.py: Integrate validation into prompt generation
   pipeline to automatically clean invalid includes

3. pdd/templates/generic/generate_prompt.prompt: Update template to instruct
   LLM to NOT assume files exist and provide alternatives for missing deps
…ores architecture.json

Problem: When architecture.json specifies filepath like "src/backend/models/findings.py",
pdd sync ignores it and uses .pddrc defaults, generating files at wrong paths.

Tests added to test_sync_determine_operation.py:
- TestSyncArchitecturePaths: Basic architecture.json filepath extraction
- TestSyncArchitecturePathIntegration: Integration tests for sync with architecture
- TestArchitectureJsonLookup: Architecture.json discovery and module matching
- TestGetPddFilePathsWithArchitecture: Verify get_pdd_file_paths uses architecture.json
… architecture.json

Solution in pdd/sync_determine_operation.py:
1. _find_architecture_json(): Search upward from CWD to find architecture.json
2. _get_filepath_from_architecture(): Extract filepath for a prompt filename
3. Modified get_pdd_file_paths(): Check architecture.json FIRST before .pddrc

Path resolution priority (highest to lowest):
1. User-specified output path (command line)
2. architecture.json filepath field
3. .pddrc context configuration
4. Default naming convention

Paths are resolved relative to architecture.json location, not CWD.
@gltanaka
Copy link
Contributor

what manual testing did you do?

@gltanaka
Copy link
Contributor

target 1/12

gltanaka and others added 7 commits January 12, 2026 23:55
…e Tool,. This is an indepth example of how to use the template tool.

- Created .gitignore to exclude unnecessary files and directories.
- Added .pddrc for project configuration settings.
- Introduced API_FAILURE_ANALYSIS.md for documenting API failure scenarios.
- Developed architecture diagram in HTML format for visual representation.
- Created architecture.json to define project structure and dependencies.
- Added README.md to provide an overview and usage instructions for the tool.
- Implemented example.py to demonstrate basic functionality.
- Included INFISICAL_SETUP.md for centralized secret management setup.
- Established Makefile for build automation and testing.
- Added project_dependencies.csv to track project dependencies.
- Created pyproject.toml for package metadata and configuration.
- Developed various example scripts to illustrate usage of the Edit File Tool.
- Implemented core functionality in src/edit_file_tool directory, including caching and cost tracking utilities.
- Added tests for core functionality and utilities to ensure reliability.
…ma validation

Unit test (test_llm_invoke.py):
- test_openai_strict_mode_schema_includes_additional_properties_false

E2E test (test_e2e_issue_295_openai_schema.py):
- Exercises full CLI path from pdd generate to litellm.completion
- Verifies additionalProperties: false is included in schema

Both tests fail on current code, confirming the bug:
- Standard completion path (llm_invoke.py:1899-1906) is missing
  additionalProperties: false that OpenAI requires for strict mode

Fixes promptdriven#295
…ests

Add failing tests for promptdriven#295: OpenAI strict mode schema validation
jiaminc-cmu and others added 20 commits January 21, 2026 19:58
Remove accidentally committed *_fixed.py files that are artifacts
from the pdd fix workflow and should not be in the repository.

Files removed:
- pdd/generate_test_pdd_fix_errors_generate_test_fixed.py
- pdd/generate_test_test_generate_test_fixed.py
- tests/test_generate_test_test_generate_test_fixed.py
Remove accidentally committed error_log.txt which is a test artifact
and should not be in the repository.
Remove accidentally committed report_python.prompt which is an artifact
from the pdd fix workflow and should not be in the repository.
After the fix to re-raise UsageError in errors.py, these tests
needed to be updated to expect exit_code 2 instead of 0 for error cases.
Add failing tests for sys.path isolation in generated tests (promptdriven#342)
Add failing tests for promptdriven#364: Cumulative cost display bug
Fix Step 10 pdd bug command to remove non-existent log file reference
feat(which): New command "pdd which" that exposes effective config and search paths (Fixes promptdriven#21)
Fix promptdriven#54: Add --format option to the example command to control output format
…-path-support

Fix promptdriven#334: Support paths with spaces in regression tests
New example for onboarding people + template for generating pddrc file
Resolved conflicts by combining both features:
- Keep Issue promptdriven#225 fixes (validate_prompt_includes + architecture.json filepath)
- Integrate new architecture_sync tags injection feature
- Merge all test cases from both branches
- Fix type checking issue in validate_prompt_includes.py by initializing parent_size to float('inf')
- Extract _ensure_trailing_slash helper to reduce code duplication in sync_determine_operation.py
- Keep is_negated as local function (only used once, no need to extract)
@Enfoirer Enfoirer force-pushed the fix/issue-225-example-import-template branch from 3364d6d to a60b4cc Compare January 24, 2026 15:26
@Enfoirer
Copy link
Contributor Author

Enfoirer commented Jan 24, 2026

Manual Testing Completed

I have completed comprehensive manual testing to verify both bugs in Issue #225 are fixed. Below are the detailed test results.

Test Setup

Created a test project structure matching the Issue #225 scenario:

Architecture Configuration (architecture.json):

{
  "modules": [
    {
      "filename": "models_findings_Python.prompt",
      "filepath": "src/backend/models/findings.py",
      "description": "Findings data model using Pydantic",
      "dependencies": []
    },
    {
      "filename": "rules_engine_Python.prompt",
      "filepath": "src/backend/rules/engine.py",
      "description": "Rules engine for processing findings",
      "dependencies": ["models_findings_Python.prompt"]
    }
  ]
}

Configuration (.pddrc):

version: "1.0"
contexts:
  default:
    defaults:
      generate_output_path: "src/"  # Would cause bug if used
      test_output_path: "tests/"
      example_output_path: "examples/"

Directory Structure:

tmp_manual_test_225/
├── architecture.json
├── .pddrc
├── prompts/
├── src/
│   └── backend/
│       ├── models/
│       └── rules/
├── tests/
└── examples/

Bug 1: Invalid <include> Tags in Generated Prompts FIXED

Issue Description

When using the generic/generate_prompt template, the LLM would generate invalid <include> tags referencing non-existent files, such as:

  • <include>[File not found: context/pydantic_example.py]</include>
  • <include>context/some_module_example.py</include> (when file doesn't exist)

Test Command

pdd --force generate --template generic/generate_prompt \
  -e MODULE=models_findings \
  -e LANG_OR_FRAMEWORK=Python \
  -e ARCHITECTURE_FILE=architecture.json \
  --output prompts/models_findings_Python.prompt

Test Result: PASS

Generated Prompt Content:

% Role: Pydantic data model for findings

% Requirements
- Define a Finding model with id, title, description, severity fields
- Use Pydantic for validation
- Include proper type hints

Dependencies
Prompt Dependencies:
- The rules_engine_Python.prompt is expected to interact with 
  the models_findings module to process findings data. It should 
  provide interfaces for rule evaluation and findings processing.

Verification Points:

  • No invalid <include> tags found
  • No [File not found: ...] placeholders
  • No assumptions about files existing in context/ directory
  • Dependencies properly documented in "Prompt Dependencies" section
  • Dependencies describe expected interfaces instead of assuming files exist

Bug 2: pdd sync Ignores architecture.json filepath FIXED

Issue Description

When architecture.json specifies a filepath like "src/backend/models/findings.py", pdd sync would ignore it and use .pddrc default paths instead, generating files at incorrect locations like src/models_findings.py.

Test Commands

# Module 1
pdd sync models_findings

# Module 2  
pdd sync rules_engine

Test Result: PASS

Module 1: models_findings

architecture.json specifies: src/backend/models/findings.py
File generated at: ./src/backend/models/findings.py

Related files also correctly placed:

  • Test: ./tests/test_findings.py
  • Example: ./examples/findings_example.py

Module 2: rules_engine

architecture.json specifies: src/backend/rules/engine.py
File generated at: ./src/backend/rules/engine.py

Related files also correctly placed:

  • Test: ./tests/test_engine.py
  • Example: ./examples/engine_example.py

Before/After Comparison

Before Fix (Bug Behavior):

  • Would generate at: src/models_findings.py (using .pddrc path)
  • Completely ignored architecture.json
  • User had to manually specify paths with --output

After Fix (Current Behavior):

  • Generates at: src/backend/models/findings.py (using architecture.json)
  • Respects filepath field in architecture.json
  • Path resolution priority correctly implemented

File Tree Verification

tmp_manual_test_225/
├── architecture.json
├── .pddrc
├── prompts/
│   ├── models_findings_Python.prompt
│   └── rules_engine_Python.prompt
├── src/
│   └── backend/
│       ├── models/
│       │   └── findings.py         ✅ Correct path
│       └── rules/
│           └── engine.py           ✅ Correct path
├── tests/
│   ├── test_findings.py
│   └── test_engine.py
└── examples/
    ├── findings_example.py
    └── engine_example.py

Path Resolution Priority Verification

The fix implements the correct priority order (from Issue #225 description):

  1. User-specified output path (command line --output)
  2. architecture.json filepath fieldNEW (this fix)
  3. .pddrc outputs config (template-based paths)
  4. .pddrc generate_output_path config
  5. Default naming conventions

Automated Test Coverage

All automated tests also pass:

pytest tests/test_validate_prompt_includes.py \
       tests/test_generate_prompt_template.py \
       tests/test_sync_determine_operation.py::TestSyncArchitecturePaths \
       tests/test_sync_determine_operation.py::TestSyncArchitecturePathIntegration \
       tests/test_sync_determine_operation.py::TestArchitectureJsonLookup \
       tests/test_sync_determine_operation.py::TestGetPddFilePathsWithArchitecture

============================== 35 passed in 2.37s ==============================

Test Breakdown:


@Enfoirer Enfoirer force-pushed the fix/issue-225-example-import-template branch from a60b4cc to 56a969d Compare January 24, 2026 15:50
Resolved conflicts by combining both features:
- Keep Issue promptdriven#225 fixes (validate_prompt_includes + architecture.json filepath)
- Integrate new architecture_sync tags injection feature
- Merge all test cases from both branches
@gltanaka
Copy link
Contributor

Review Findings

Both bugs addressed in this PR are real and confirmed by testing against main. The fixes work, but there's one naming bug to address before merge.

Bug 1 (Invalid <include> tags) — Confirmed real, fix works

The current template (line 139) instructs the LLM to assume files exist:

"If examples are not provided, use the example_output_path from .pddrc with the pattern..."

The template text change correctly fixes this. The validate_prompt_includes module also works — tested with simulated LLM output containing fabricated <include> tags, and it correctly replaces them with <!-- Missing: ... --> comments or removes the parent XML block.

Bug 2 (pdd sync ignores architecture.json filepath) — Confirmed real, fix works but has a naming bug

Verified that sync_determine_operation.py has zero references to "architecture" or "filepath" on main — the filepath field is completely ignored. The fix correctly reads architecture.json and resolves paths:

WITHOUT architecture.json: src/models_findings.py
WITH    architecture.json: src/backend/models/findings.py

However, there's a bug in how example/test paths are derived. At sync_determine_operation.py:559:

code_stem = code_path.stem  # "findings"

This uses the code file stem (findings) instead of the basename parameter (models_findings) for example and test naming. Per the README naming convention:

  • Example default: <basename>_example.<ext>
  • Test default: test_<basename>.<ext>

Current behavior with this PR:

File PR produces README convention
Code src/backend/models/findings.py ✅ correct (from architecture.json)
Example findings_example.py ❌ should be models_findings_example.py
Test test_findings.py ❌ should be test_models_findings.py

Fix: Line 559 should use the basename parameter already passed to get_pdd_file_paths() instead of code_path.stem.

Minor issues

  • CLOUD_REQUEST_TIMEOUT = 400 added to code_generator_main.py (line 107) but never used — appears copied from fix_code_loop.py by accident
  • Some tests reimplement functions inline rather than importing the actual code under test (e.g., TestArchitectureJsonLookup defines its own find_architecture_json instead of importing _find_architecture_json)

@gltanaka gltanaka marked this pull request as draft January 29, 2026 20:53
- Fix naming bug: use basename instead of code_path.stem for example/test paths
  (e.g., models_findings_example.py instead of findings_example.py)
- Remove unused CLOUD_REQUEST_TIMEOUT constant from code_generator_main.py
- Refactor TestArchitectureJsonLookup to import actual functions instead of
  inline reimplementation
@Enfoirer
Copy link
Contributor Author

Thanks for the detailed review! All issues have been addressed in the latest commit:

Naming Bug ✅ Fixed

  • Changed code_path.stem to basename for example/test path generation
  • Now correctly produces models_findings_example.py and test_models_findings.py instead of findings_example.py and test_findings.py

Minor Issues ✅ Fixed

  • Removed unused CLOUD_REQUEST_TIMEOUT = 400 from code_generator_main.py
  • Refactored TestArchitectureJsonLookup to import actual functions (_find_architecture_json, _get_filepath_from_architecture) instead of inline reimplementation

All 35 Issue #225 related tests pass.

@Enfoirer Enfoirer marked this pull request as ready for review January 30, 2026 16:53
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.

Example import issue with template

8 participants