From 23cc23c689f974b6e68651269aec3de6d7879e8f Mon Sep 17 00:00:00 2001 From: Serhan Date: Wed, 8 Jul 2026 15:01:54 -0700 Subject: [PATCH 01/30] fix(sync): surgical (edit-shaped) regeneration for mature modules + --fresh (#1938) pdd sync regenerated mature modules "rebirth-shaped" (full regeneration), dropping declared public symbols. PDD already ships edit-shaped generation (incremental_code_generator + code_patcher_LLM), but sync hardcoded force_incremental_flag=False, so it deferred to the deliberately-conservative diff_analyzer_LLM ("prefer complete regeneration"), which rebirthed modules on ordinary small prompt deltas and lost symbols. Make sync prefer surgical generation for mature modules, with a --fresh opt-out: - New `pdd sync --fresh` flag (default off), threaded sync -> sync_main -> sync_orchestration and the one-session generate loop. - Both sync generate call sites now pass force_incremental_flag=(not fresh): default -> surgical/edit-shaped (existing code + prompt delta -> minimal edit, declared symbols preserved); --fresh -> standard generation. - Reuses existing infra only. Safety nets preserved: new/empty modules still full-generate; undeterminable original prompt falls back to full generation; conformance repair retries still force full regeneration (#1724); the public-surface / declared-interface gate (#1900) is unchanged and remains the guarantee. - --fresh is single-module only: raises UsageError on global/agentic sync paths (mirrors --snapshot-context) instead of silently no-op'ing. Prompt sources edited in tandem with generated .py (pdd is self-hosted); sync_main's architecture.json signature aligned; README documents the flag. Co-Authored-By: Claude Opus 4.8 --- README.md | 3 +- architecture.json | 2 +- pdd/commands/maintenance.py | 19 +++++++ .../commands/maintenance_python.prompt | 1 + pdd/prompts/sync_main_python.prompt | 7 ++- pdd/prompts/sync_orchestration_python.prompt | 4 +- pdd/sync_main.py | 11 +++- pdd/sync_orchestration.py | 12 +++- tests/commands/test_maintenance.py | 45 +++++++++++++++ tests/test_sync_main.py | 53 ++++++++++++++++++ tests/test_sync_orchestration.py | 55 +++++++++++++++++++ 11 files changed, 204 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6a7d4d0750..0d3ab49c1c 100644 --- a/README.md +++ b/README.md @@ -1041,6 +1041,7 @@ Options: - `--skip-tests`: Skip unit test generation and fixing - `--target-coverage FLOAT`: Desired code coverage percentage (default is 90.0) - `--compress`: Use AST-based compression for Python few-shot examples (strips docstrings and logic-external comments). Helps fit more context into limited LLM windows without losing executable logic. +- `--fresh`: Disable the default surgical/edit-shaped regeneration of a mature module. By default, when a module already has non-empty code and its prompt changed, `pdd sync` edits the existing code in place (feeding the current code plus the prompt delta to the generator) so declared public symbols are preserved rather than dropped by a from-scratch rewrite. With `--fresh`, sync uses standard generation, which regenerates the module from scratch when the prompt change is large — use it when you intend a large rewrite rather than an in-place edit. New/empty modules are always generated fresh, and the public-surface / declared-interface gate still guards either path. `--fresh` acts on the standard multi-step single-module sync; in one-session/agentic sync the code is regenerated by the agent session, so `--fresh` only affects from-scratch (re)generation there. Single-module sync only: passing `--fresh` to project-wide (no-argument) or GitHub-issue agentic sync raises a `UsageError`. - `--dry-run`: Display real-time sync analysis instead of running sync operations. For no-argument project-wide sync, this prints the dependency-ordered module list and estimated cost without executing any module syncs, plus a single compact roll-up of modules outside the Tier 1 (`generate` / `auto-deps`) scope — bucketed by reason (e.g. `Out of Tier 1 scope: 42 example, 31 test, 18 verify, 12 update, 74 no-prompt fixture`) instead of one warning line per skipped entry. When zero modules are stale, the `0 stale module(s)` fragment is rendered in green so the success signal is visually unambiguous. Actionable architecture-graph warnings (ambiguous or unresolved cross-arch dependencies) are still printed individually in yellow. For single-module sync, it performs the same state analysis as a normal sync run but without acquiring exclusive locks or executing operations. Passing the top-level `pdd --verbose` flag (see above) restores the legacy per-module enumeration after the compact roll-up — one yellow warning line per module outside the Tier 1 scope — for debugging. - `--snapshot-context`: Capture the fully expanded prompt context used for generation, including nondeterministic ``, ``, and `` outputs. The run manifest is `.pdd/evidence/runs/.json`; snapshot artifacts are in `.pdd/evidence/runs//`. Replay can later reconstruct the same prompt/context from the recorded run artifact. - `--compressed-context / --no-compressed-context`: Enable or disable compressed sync context for generation and repair phases. This option is tri-state internally: omitting it lets `.pddrc` `defaults.compressed_context` apply, `--compressed-context` forces it on, and `--no-compressed-context` forces it off. When enabled, sync builds bounded phase packages from the prompt, existing tests, examples when present, contract sections, and recent repair evidence, then passes those packages to generate, verify, test, and fix attempts. The sync result records whether compression was used and whether any agentic fallback was needed. @@ -1158,7 +1159,7 @@ pdd sync --no-one-session https://github.com/myorg/myrepo/issues/100 - **Smart Lock Management**: Prevents concurrent sync operations with automatic stale lock cleanup - Detects which files already exist and are up-to-date - Skips unnecessary steps (e.g., won't regenerate code if prompt hasn't changed) -- Uses git integration to detect changes and determine incremental vs full regeneration +- Uses git integration to detect changes; regenerates mature modules surgically (edit-shaped) by default so declared symbols are preserved, falling back to full regeneration for new modules or when `--fresh` is passed - Accumulates tests over time rather than replacing them (in a single test file per target) - Automatically handles dependencies between steps - **Compressed Context Telemetry**: Sync results and logs record whether compressed context was requested, the effective value after CLI and `.pddrc` resolution, whether it was actually applied for each phase, the source inputs used to build it, and whether the run fell back to agentic repair. This makes replay and benchmark comparisons distinguish normal sync from compressed-context sync. diff --git a/architecture.json b/architecture.json index fbbc3de48c..26e99a199e 100644 --- a/architecture.json +++ b/architecture.json @@ -5505,7 +5505,7 @@ "commands": [ { "name": "sync_main", - "signature": "(ctx: click.Context, basename: str, max_attempts: Optional[int], budget: Optional[float], skip_verify: bool, skip_tests: bool, target_coverage: float, dry_run: bool, no_steer: bool = False, steer_timeout: Optional[float] = None, agentic_mode: bool = False, one_session: bool = False, compress: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: Optional[bool] = None) -> Tuple[Dict[str, Any], float, str]", + "signature": "(ctx: click.Context, basename: str, max_attempts: Optional[int], budget: Optional[float], skip_verify: bool, skip_tests: bool, target_coverage: float, dry_run: bool, no_steer: bool = False, steer_timeout: Optional[float] = None, agentic_mode: bool = False, one_session: bool = False, compress: bool = False, fresh: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: Optional[bool] = None) -> Tuple[Dict[str, Any], float, str]", "returns": "Tuple[Dict[str, Any], float, str]" } ] diff --git a/pdd/commands/maintenance.py b/pdd/commands/maintenance.py index e8ea5a2ef9..ace1aff15f 100644 --- a/pdd/commands/maintenance.py +++ b/pdd/commands/maintenance.py @@ -210,6 +210,19 @@ def _write_sync_evidence_manifest( "(auto-deps tags and generate preprocess expansion)." ), ) +@click.option( + "--fresh", + is_flag=True, + default=False, + help=( + "Disable the default surgical (edit-shaped) regeneration for a mature " + "module. By default `pdd sync` edits existing module code in place so " + "declared symbols are preserved; with --fresh, sync uses standard " + "generation, which regenerates the module from scratch when the prompt " + "change is large. Use it when you intend a large rewrite rather than an " + "in-place edit. Single-module sync only." + ), +) @click.option( "--compressed-context/--no-compressed-context", default=None, @@ -277,6 +290,7 @@ def sync( evidence: bool, snapshot_context: bool, compress: bool, + fresh: bool, compressed_context: Optional[bool], model: Optional[str] = None, compress_examples: Optional[bool] = None, @@ -349,6 +363,8 @@ def _restore_model_default(_prev=_prev_model_default): if basename is None: if snapshot_context: raise click.UsageError("--snapshot-context is only supported for single-module sync.") + if fresh: + raise click.UsageError("--fresh is only supported for single-module sync.") if durable or durable_branch or no_resume or durable_max_parallel is not None: raise click.UsageError("Durable sync options require a GitHub issue URL.") effective_one_session = one_session if one_session is not None else False @@ -393,6 +409,8 @@ def _restore_model_default(_prev=_prev_model_default): if _is_github_issue_url(basename): if snapshot_context: raise click.UsageError("--snapshot-context is only supported for single-module sync.") + if fresh: + raise click.UsageError("--fresh is only supported for single-module sync.") if not durable and ( durable_branch is not None or no_resume or durable_max_parallel is not None ): @@ -473,6 +491,7 @@ def _restore_model_default(_prev=_prev_model_default): one_session=effective_one_session, snapshot_context=snapshot_context, compress=compress, + fresh=fresh, compressed_context=effective_compressed_context, ) if evidence: diff --git a/pdd/prompts/commands/maintenance_python.prompt b/pdd/prompts/commands/maintenance_python.prompt index 80cbd19795..56c21f2fd8 100644 --- a/pdd/prompts/commands/maintenance_python.prompt +++ b/pdd/prompts/commands/maintenance_python.prompt @@ -43,6 +43,7 @@ - `--skip-tests` (`is_flag=True`, `default=False`): Skip unit test generation/fixing. - `--target-coverage` (`type=float`, `default=None`): Desired coverage percentage. Help mentions "Default: 90.0 or .pddrc value." - `--dry-run` (`is_flag=True`, `default=False`): Analyze sync state without executing operations. + - `--fresh` (`is_flag=True`, `default=False`): Disable the default surgical/edit-shaped regeneration of a mature module (#1938 Pillar A). For single-module sync, forward to `sync_main()` as `fresh`; the single-module sync path drives `code_generator_main` with `force_incremental_flag=(not fresh)`, so mature modules are edited in place by default and, when `--fresh` is passed, standard generation is used instead (which regenerates the module from scratch when the prompt change is large). `--fresh` is single-module only: when BASENAME is omitted (global sync) or is a GitHub issue URL (agentic sync), raise `click.UsageError("--fresh is only supported for single-module sync.")` BEFORE dispatch — exactly like `--snapshot-context` — rather than silently dropping the flag. Help: "Disable the default surgical (edit-shaped) regeneration for a mature module; with --fresh, sync uses standard generation, which regenerates the module from scratch when the prompt change is large. Use it when you intend a large rewrite rather than an in-place edit. Single-module sync only." - `--snapshot-context` (`is_flag=True`, `default=False`): Capture replayable expanded prompt context for generation-time prompt expansion. For single-module sync, forward to `sync_main`. For project-wide sync, forward only if the downstream global sync path supports it; otherwise raise `click.UsageError`. For GitHub issue sync, either forward explicitly through `run_agentic_sync` when supported or raise `click.UsageError` so unsupported snapshot requests are not silently ignored. - `--compressed-context/--no-compressed-context` (Click flag/no-flag syntax, `default=None`): TRI-STATE. `None` means "no CLI value supplied"; `True` and `False` are explicit user choices. Enable phase-aware compressed context for sync generation and repair phases. This is distinct from `--snapshot-context`: snapshots record replayable expanded prompt context, while compressed context supplies bounded prompt/test/example/contract evidence to generate, verify, test, and fix phases. Resolve the effective value as `compressed_context if compressed_context is not None else .pddrc defaults.compressed_context if present else False`. Forward the resolved bool to `sync_main`, `_run_global_sync_dispatch`, and `_run_agentic_sync_dispatch` when the downstream path supports it; if the user explicitly requests compressed context on a path that cannot honor it, raise a clear `click.UsageError` instead of silently ignoring it. - `--log` (`is_flag=True`, `default=False`, `hidden=True`): Deprecated. When set, emit `click.echo(click.style("Warning: --log is deprecated, use --dry-run instead.", fg="yellow"), err=True)` and then set `dry_run = True` before any dispatch. diff --git a/pdd/prompts/sync_main_python.prompt b/pdd/prompts/sync_main_python.prompt index 7343df20bd..7712e9aa09 100644 --- a/pdd/prompts/sync_main_python.prompt +++ b/pdd/prompts/sync_main_python.prompt @@ -5,7 +5,7 @@ "type": "cli", "cli": { "commands": [ - {"name": "sync_main", "signature": "(ctx: click.Context, basename: str, max_attempts: Optional[int], budget: Optional[float], skip_verify: bool, skip_tests: bool, target_coverage: float, dry_run: bool, no_steer: bool = False, steer_timeout: Optional[float] = None, agentic_mode: bool = False, one_session: bool = False, compress: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: Optional[bool] = None) -> Tuple[Dict[str, Any], float, str]", "returns": "Tuple[Dict[str, Any], float, str]"} + {"name": "sync_main", "signature": "(ctx: click.Context, basename: str, max_attempts: Optional[int], budget: Optional[float], skip_verify: bool, skip_tests: bool, target_coverage: float, dry_run: bool, no_steer: bool = False, steer_timeout: Optional[float] = None, agentic_mode: bool = False, one_session: bool = False, compress: bool = False, fresh: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: Optional[bool] = None) -> Tuple[Dict[str, Any], float, str]", "returns": "Tuple[Dict[str, Any], float, str]"} ] } } @@ -41,6 +41,7 @@ - `steer_timeout` (Optional[float]): Steering choice timeout in seconds. None = default timeout. - `agentic_mode` (bool): When True, Python behaves like non-Python languages (uses agentic path for operations) - `one_session` (bool): When True, run example/crash/verify/test/fix in a single agentic session instead of separate steps + - `fresh` (bool): Issue #1938 Pillar A. When False (default), regenerate mature modules surgically (edit-shaped) by passing `force_incremental_flag=True` to `code_generator_main` so declared public symbols are preserved instead of dropped by a full "rebirth" regeneration. When True (`pdd sync --fresh`), pass `force_incremental_flag=False` to restore standard generation. Forward `fresh` to every `sync_orchestration()` call and use `force_incremental_flag=(not fresh)` in the one-session generation loop. Note: in one-session mode the module is otherwise (re)generated by the agent session (`run_one_session_sync`), so the one-session `code_generator_main` generate — and therefore `fresh` — only takes effect when the code file is missing or `--force` triggers a from-scratch generation; for an already-existing mature module in one-session mode the code edit is agent-driven and `fresh` does not change it. The effective path for `fresh` is the standard multi-step single-module sync. Default False. - `snapshot_context` (bool): When True, capture replayable expanded prompt context for generation in `code_generator_main` and `sync_orchestration`. Default False. - `compressed_context` (Optional[bool]): Tri-state request flag for phase-aware compressed context. `None` means no explicit CLI value was supplied; resolve the effective setting from CLI value when not None, then `.pddrc` default context `defaults.compressed_context`, then `False`. Display the effective setting with other sync settings and never print raw compressed prompt/test/example content. - `compress` (bool): Use AST-based compression (`mode="compressed"`) for Python includes when no explicit include mode is set. Default False. @@ -111,7 +112,7 @@ - Mutually exclusive with `skip_tests` and `skip_verify` (raise UsageError if combined) - Use `get_pdd_file_paths()` from `sync_determine_operation` to resolve module file paths - **Fingerprint check**: If not force mode, call `sync_determine_operation()` to check if module is already synced; skip if operation is "nothing" - - **Phase 1 (Generation)**: If code file doesn't exist or `force`, run `code_generator_main()` to generate the code file; track the generation cost as `pre_cost`. Pass `output_from_config=True` — the resolved code path comes from `get_pdd_file_paths()` (which uses `.pddrc` `generate_output_path`), not an explicit user `--output` flag, so front-matter `output:` should still take precedence over the .pddrc default. Forward `snapshot_context` into every generation attempt. When the effective compressed-context request flag is true, build a phase-specific compressed context package immediately before each LLM-backed generation attempt and pass that mapping to `code_generator_main(compressed_context=package)`. Never pass the boolean request flag itself to `code_generator_main`. If package construction fails, pass `None`, continue with full-context behavior, and record `used=false` compression metadata with the failure reason. + - **Phase 1 (Generation)**: If code file doesn't exist or `force`, run `code_generator_main()` to generate the code file; track the generation cost as `pre_cost`. Pass `output_from_config=True` — the resolved code path comes from `get_pdd_file_paths()` (which uses `.pddrc` `generate_output_path`), not an explicit user `--output` flag, so front-matter `output:` should still take precedence over the .pddrc default. Pass `force_incremental_flag=(not fresh)` so a mature module (existing non-empty code file) is regenerated surgically/edit-shaped by default and only fully regenerated when the operator passes `--fresh` (#1938 Pillar A); `code_generator_main` still falls back to full generation for a new/empty file or when the original prompt cannot be determined. Forward `snapshot_context` into every generation attempt. When the effective compressed-context request flag is true, build a phase-specific compressed context package immediately before each LLM-backed generation attempt and pass that mapping to `code_generator_main(compressed_context=package)`. Never pass the boolean request flag itself to `code_generator_main`. If package construction fails, pass `None`, continue with full-context behavior, and record `used=false` compression metadata with the failure reason. - **Ambiguous module names (issue #1677)**: catch `AmbiguousModuleError` (imported from `sync_determine_operation`; a `ValueError` subclass raised by `get_pdd_file_paths` when a bare basename maps to ≥2 distinct architecture outputs) around module/path resolution and the per-language loop, and fail the command hard with the conflicting-target list (shown even under `--quiet`, exit non-zero). Never fall through to first-match-wins generation for an ambiguous bare basename. - **Architecture-conformance / public-surface / test-churn retry (#866, #1012)**: Wrap the `code_generator_main()` call in a retry loop bounded by `MAX_CONFORMANCE_ATTEMPTS` (imported from `pdd.agentic_sync_runner`). The loop catches three typed exceptions raised from `code_generator_main`: `ArchitectureConformanceError`, `PublicSurfaceRegressionError`, and `TestChurnError`. For each, add `exc.total_cost` to `pre_cost`, remember `exc.model_name`, set `PDD_REPAIR_DIRECTIVE` to `exc.repair_directive`, and retry only if budget remains. - Track the failure signature across attempts: sorted `missing_symbols` for conformance, sorted `removed_symbols` for public-surface, `(round(churn_ratio, 2), pre_line_count)` for test-churn. If the next attempt fails with the **identical** signature, abort the loop (no progress) instead of looping forever. Test-churn additionally caps at ONE repair attempt — the additive-only directive either lands the first try or stays stuck. @@ -145,7 +146,7 @@ - Track remaining_budget across languages (reduce after each language's cost) - Skip subsequent languages if budget exhausted - Aggregate results and costs from all language syncs - - Forward steerability controls (`no_steer`, resolved `steer_timeout`), `compress`, `evidence`, and #877 compression flags (`compress_examples`, `compress_test_context`, `context_compression`, `compression_fallback`) to each sync_orchestration call + - Forward steerability controls (`no_steer`, resolved `steer_timeout`), `compress`, `fresh`, `evidence`, and #877 compression flags (`compress_examples`, `compress_test_context`, `context_compression`, `compression_fallback`) to each sync_orchestration call - **Auto-submit on success**: After sync_orchestration returns success for a language (and not local mode), call `_auto_submit_example()` to submit the prompt+code pair to PDD Cloud, same as one-session mode. Use `get_pdd_file_paths()` to resolve the module file paths needed for submission. Wrap in try/except and log warnings on failure (do not abort sync). 11. User Feedback (unless quiet=True): diff --git a/pdd/prompts/sync_orchestration_python.prompt b/pdd/prompts/sync_orchestration_python.prompt index 638faa76ad..c863b16d6a 100644 --- a/pdd/prompts/sync_orchestration_python.prompt +++ b/pdd/prompts/sync_orchestration_python.prompt @@ -5,7 +5,7 @@ "type": "module", "module": { "functions": [ - {"name": "sync_orchestration", "signature": "(basename: str, target_coverage: float = 90.0, language: str = \"python\", prompts_dir: str = \"prompts\", code_dir: str = \"src\", examples_dir: str = \"examples\", tests_dir: str = \"tests\", max_attempts: int = 3, budget: float = 10.0, skip_verify: bool = False, skip_tests: bool = False, dry_run: bool = False, force: bool = False, strength: float = DEFAULT_STRENGTH, temperature: float = 0.0, time_param: float = 0.25, verbose: bool = False, quiet: bool = False, output_cost: Optional[str] = None, review_examples: bool = False, local: bool = False, context_config: Optional[Dict[str, str]] = None, context_override: Optional[str] = None, confirm_callback: Optional[Callable[[str, str], bool]] = None, no_steer: bool = False, steer_timeout: float = DEFAULT_STEER_TIMEOUT_S, agentic_mode: bool = False, one_session: bool = False, compress: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: bool = False) -> Dict[str, Any]", "returns": "Dict[str, Any]"} + {"name": "sync_orchestration", "signature": "(basename: str, target_coverage: float = 90.0, language: str = \"python\", prompts_dir: str = \"prompts\", code_dir: str = \"src\", examples_dir: str = \"examples\", tests_dir: str = \"tests\", max_attempts: int = 3, budget: float = 10.0, skip_verify: bool = False, skip_tests: bool = False, dry_run: bool = False, force: bool = False, strength: float = DEFAULT_STRENGTH, temperature: float = 0.0, time_param: float = 0.25, verbose: bool = False, quiet: bool = False, output_cost: Optional[str] = None, review_examples: bool = False, local: bool = False, context_config: Optional[Dict[str, str]] = None, context_override: Optional[str] = None, confirm_callback: Optional[Callable[[str, str], bool]] = None, no_steer: bool = False, steer_timeout: float = DEFAULT_STEER_TIMEOUT_S, agentic_mode: bool = False, one_session: bool = False, compress: bool = False, fresh: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: bool = False) -> Dict[str, Any]", "returns": "Dict[str, Any]"} ] } } @@ -73,6 +73,7 @@ def sync_orchestration( steer_timeout: float = DEFAULT_STEER_TIMEOUT_S, agentic_mode: bool = False, compress: bool = False, + fresh: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: bool = False, @@ -305,6 +306,7 @@ When `skip_verify` or `skip_tests` is set: - For the **auto-deps** operation, invoke `auto_deps_main()` with the resolved prompt path, directory path, CSV path, and `_skip_finalization=True`. Pass `compress=compress`. - For the **generate** operation, invoke `code_generator_main()` with the resolved `pdd_files['prompt']` and `pdd_files['code']` (both `.resolve()`'d to absolute paths). Pass `output_from_config=True` — the resolved code path comes from `get_pdd_file_paths()` (which uses `.pddrc generate_output_path`), not an explicit user `--output`, so front-matter `output:` should still take precedence over the .pddrc default. Forward `compress` and `snapshot_context` during normal generation and during conformance retry attempts. When compressed context is requested, build a fresh `phase="generate"` package for each initial attempt and retry, then pass it as `compressed_context=` to `code_generator_main`; never pass the boolean request flag. The one-session sync path in `sync_main` follows the same convention. + - **Surgical regeneration for mature modules (#1938 Pillar A)**: pass `force_incremental_flag=(not fresh)` to `code_generator_main` — i.e. by DEFAULT (`fresh=False`) mature modules are regenerated surgically (edit-shaped): `code_generator_main` feeds the existing on-disk code plus the prompt delta to the incremental generator so declared public symbols are preserved in place rather than dropped by a full "rebirth" regeneration. When the operator passes `pdd sync --fresh` (`fresh=True`), forward `force_incremental_flag=False` to restore full regeneration (for intended large rewrites). This applies to the initial generate attempt AND the conformance retry attempts; `code_generator_main` itself keeps the safety fallbacks — it performs full generation for a new/empty module or when the original prompt cannot be determined, and it disables incremental generation whenever a `PDD_REPAIR_DIRECTIVE` is active so repair retries still reach the full generator (#1724). The public-surface / declared-interface gate remains the guarantee; surgical generation only lowers drift frequency at the source. The one-session sync path in `sync_main` passes the same `force_incremental_flag=(not fresh)`. - **Ambiguous module names (issue #1677)**: `get_pdd_file_paths` raises `AmbiguousModuleError` (a `ValueError` subclass listing the conflicting targets) when a bare basename maps to ≥2 distinct architecture outputs. `sync_orchestration` imports it from `sync_determine_operation` and must let it propagate in BOTH the dry-run/log-display path and the main path — do NOT swallow it in the broad per-operation `except` — so an ambiguous bare basename fails the sync fast instead of generating to a guessed default path. - **Architecture-conformance / public-surface / test-churn retry (#866, #1012)**: Wrap the **generate** invocation of `code_generator_main()` in a repair loop bounded by `MAX_CONFORMANCE_ATTEMPTS` (imported from `pdd.agentic_sync_runner`). The loop catches three typed exceptions from `code_generator_main` — `ArchitectureConformanceError`, `PublicSurfaceRegressionError`, and `TestChurnError` — and routes each through the same `PDD_REPAIR_DIRECTIVE` plumbing: - On `ArchitectureConformanceError`: accumulate `exc.total_cost`/`exc.model_name`, set `PDD_REPAIR_DIRECTIVE` to `exc.repair_directive`, and retry only while budget remains; abort early (without further attempts) when the next failure carries the **identical** sorted missing-symbol set as the previous one (no progress is being made). On exhaustion call `build_conformance_hard_failure_from_error(last_exc, basename)` and `print()` the structured block to **stderr** (it contains `prompt:`, `output:`, `expected:`, `found:`, `missing:`, `Reproduce locally: pdd sync `, and the `--- env ---` fingerprint) before re-raising `last_exc`. diff --git a/pdd/sync_main.py b/pdd/sync_main.py index 8ca29b5a12..c8f72cdff4 100644 --- a/pdd/sync_main.py +++ b/pdd/sync_main.py @@ -610,6 +610,7 @@ def sync_main( agentic_mode: bool = False, one_session: bool = False, compress: bool = False, + fresh: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: bool = False, @@ -1064,7 +1065,14 @@ def _one_session_compressed_context( prompt_file=str(pdd_files["prompt"].resolve()), output=str(pdd_files["code"].resolve()), original_prompt_file_path=None, - force_incremental_flag=False, + # Surgical (edit-shaped) regeneration by + # default for mature modules; --fresh + # (fresh=True) restores full regeneration + # (#1938 Pillar A). code_generator_main + # still falls back to full generation for + # new/empty modules or when the original + # prompt can't be determined. + force_incremental_flag=not fresh, language=resolved_language, # output is .pddrc-derived (get_pdd_file_paths uses # context config), so let front-matter override it. @@ -1272,6 +1280,7 @@ def _one_session_compressed_context( agentic_mode=agentic_mode, snapshot_context=snapshot_context, compressed_context=compressed_context, + fresh=fresh, ) # Post-sync: auto-submit example to cloud on success (multi-step path) diff --git a/pdd/sync_orchestration.py b/pdd/sync_orchestration.py index 4e7e70c145..9385fc6c87 100644 --- a/pdd/sync_orchestration.py +++ b/pdd/sync_orchestration.py @@ -2003,12 +2003,22 @@ def sync_orchestration( steer_timeout: float = DEFAULT_STEER_TIMEOUT_S, agentic_mode: bool = False, compress: bool = False, + fresh: bool = False, evidence: bool = False, snapshot_context: bool = False, compressed_context: bool = False, ) -> Dict[str, Any]: """ Orchestrates the complete PDD sync workflow with parallel animation. + + ``fresh`` (issue #1938 Pillar A): when False (the default), the generate + operation regenerates mature modules surgically (edit-shaped) by driving + ``code_generator_main`` with ``force_incremental_flag=True`` so declared + public symbols are preserved instead of being dropped by a full "rebirth" + regeneration. Pass ``fresh=True`` (``pdd sync --fresh``) to restore full + regeneration. ``code_generator_main`` still falls back to full generation + for new/empty modules or when the original prompt cannot be determined, and + conformance repair retries still force full regeneration. """ # Handle None values from CLI (Issue #194) - defense in depth if target_coverage is None: @@ -2746,7 +2756,7 @@ def sync_worker_logic(): for _conform_attempt in range(MAX_CONFORMANCE_ATTEMPTS): try: # Use absolute paths to avoid path_resolution_mode mismatch between sync (cwd) and generate (config_base) - result = code_generator_main(ctx, prompt_file=str(pdd_files['prompt'].resolve()), output=str(pdd_files['code'].resolve()), original_prompt_file_path=None, force_incremental_flag=False, output_from_config=True, compress=compress, snapshot_context=snapshot_context, compressed_context=_phase_compressed_context('generate', os.environ.get("PDD_REPAIR_DIRECTIVE"))) + result = code_generator_main(ctx, prompt_file=str(pdd_files['prompt'].resolve()), output=str(pdd_files['code'].resolve()), original_prompt_file_path=None, force_incremental_flag=not fresh, output_from_config=True, compress=compress, snapshot_context=snapshot_context, compressed_context=_phase_compressed_context('generate', os.environ.get("PDD_REPAIR_DIRECTIVE"))) last_conform_exc = None break except ( diff --git a/tests/commands/test_maintenance.py b/tests/commands/test_maintenance.py index c26180762d..62f56675fa 100644 --- a/tests/commands/test_maintenance.py +++ b/tests/commands/test_maintenance.py @@ -100,6 +100,51 @@ def test_sync_dry_run(self, runner, base_ctx_obj): assert result.exit_code == 0 assert mock_sm.call_args.kwargs["dry_run"] is True + def test_sync_fresh_flag_forwarded(self, runner, base_ctx_obj): + """`pdd sync --fresh` forwards fresh=True to sync_main; default is + fresh=False so mature modules regenerate surgically (#1938 Pillar A).""" + mock_result = ({"success": True}, 0.0, "none") + cli = _make_cli(sync, base_ctx_obj) + + with patch("pdd.commands.maintenance.sync_main", return_value=mock_result) as mock_sm: + result = runner.invoke(cli, ["sync", "calc", "--fresh"], catch_exceptions=False) + assert result.exit_code == 0 + assert mock_sm.call_args.kwargs["fresh"] is True + + with patch("pdd.commands.maintenance.sync_main", return_value=mock_result) as mock_sm: + result = runner.invoke(cli, ["sync", "calc"], catch_exceptions=False) + assert result.exit_code == 0 + assert mock_sm.call_args.kwargs["fresh"] is False + + def test_sync_fresh_rejected_on_global_sync(self, runner, base_ctx_obj): + """--fresh is single-module only: reject on no-argument global sync + instead of silently dropping it (#1938).""" + cli = _make_cli(sync, base_ctx_obj) + + with patch("pdd.commands.maintenance._run_global_sync_dispatch") as mock_global, \ + patch("pdd.commands.maintenance.run_agentic_sync") as mock_agentic: + result = runner.invoke(cli, ["sync", "--fresh"]) + + assert result.exit_code != 0 + assert "single-module sync" in result.output + mock_global.assert_not_called() + mock_agentic.assert_not_called() + + def test_sync_fresh_rejected_on_agentic_url_sync(self, runner, base_ctx_obj): + """--fresh is single-module only: reject on GitHub-issue agentic sync + instead of silently dropping it (#1938).""" + cli = _make_cli(sync, base_ctx_obj) + + with patch("pdd.commands.maintenance._is_github_issue_url", return_value=True), \ + patch("pdd.commands.maintenance.run_agentic_sync") as mock_agentic: + result = runner.invoke(cli, [ + "sync", "https://github.com/org/repo/issues/7", "--fresh", + ]) + + assert result.exit_code != 0 + assert "single-module sync" in result.output + mock_agentic.assert_not_called() + def test_sync_without_basename_dispatches_global_sync_not_durable( self, runner, diff --git a/tests/test_sync_main.py b/tests/test_sync_main.py index 3b9dc9d778..1d0f3ea599 100644 --- a/tests/test_sync_main.py +++ b/tests/test_sync_main.py @@ -262,6 +262,59 @@ def test_sync_main_forwards_compress_to_orchestration( assert mock_sync_orchestration.call_args.kwargs["compress"] is True +def test_sync_main_defaults_to_surgical_fresh_false( + mock_project_dir, mock_construct_paths, mock_sync_orchestration +): + """Default sync forwards fresh=False so mature modules regenerate + surgically (edit-shaped) rather than being rebirthed (#1938 Pillar A).""" + (mock_project_dir / "prompts" / "demo_python.prompt").touch() + mock_sync_orchestration.return_value = { + "success": True, + "total_cost": 0.0, + "model_name": "test", + "summary": "ok", + } + ctx = create_mock_context({"quiet": True}) + sync_main( + ctx, + "demo", + max_attempts=1, + budget=5.0, + skip_verify=True, + skip_tests=True, + target_coverage=90.0, + dry_run=False, + ) + assert mock_sync_orchestration.call_args.kwargs["fresh"] is False + + +def test_sync_main_forwards_fresh_true_to_orchestration( + mock_project_dir, mock_construct_paths, mock_sync_orchestration +): + """`pdd sync --fresh` threads fresh=True into sync_orchestration so the + operator opts back into full ('fresh') regeneration (#1938 Pillar A).""" + (mock_project_dir / "prompts" / "demo_python.prompt").touch() + mock_sync_orchestration.return_value = { + "success": True, + "total_cost": 0.0, + "model_name": "test", + "summary": "ok", + } + ctx = create_mock_context({"quiet": True}) + sync_main( + ctx, + "demo", + max_attempts=1, + budget=5.0, + skip_verify=True, + skip_tests=True, + target_coverage=90.0, + dry_run=False, + fresh=True, + ) + assert mock_sync_orchestration.call_args.kwargs["fresh"] is True + + def test_sync_success_multiple_languages(mock_project_dir, mock_construct_paths, mock_sync_orchestration): """Tests a successful sync for multiple languages, checking budget reduction and result aggregation.""" (mock_project_dir / "prompts" / "my_lib_python.prompt").touch() diff --git a/tests/test_sync_orchestration.py b/tests/test_sync_orchestration.py index 16d9c86644..3a6f29d75b 100644 --- a/tests/test_sync_orchestration.py +++ b/tests/test_sync_orchestration.py @@ -9500,3 +9500,58 @@ def test_sync_orchestration_skip_handler_for_fix(orchestration_fixture): orchestration_fixture['_save_fingerprint_atomic'].assert_any_call( "calculator", "python", "skip:fix", ANY, 0.0, "skipped" ) + + +# --------------------------------------------------------------------------- +# Issue #1938 (Pillar A): surgical regeneration for mature modules. +# +# For a mature module (existing non-empty code) with a small prompt delta, +# `pdd sync` regeneration must be edit-shaped, not rebirth-shaped, so declared +# symbols are preserved instead of dropped by a full "big change" regen. The +# generate operation therefore drives `code_generator_main` with +# `force_incremental_flag=True` by DEFAULT (surgical/edit-shaped), and only with +# `force_incremental_flag=False` (today's full-regeneration behavior) when the +# operator opts in via `pdd sync --fresh`. The `code_generator_main` layer keeps +# the existing safety nets: a new/empty module or an undeterminable original +# prompt still falls back to full generation, and a repair directive still +# forces full regeneration. +# --------------------------------------------------------------------------- +def _capture_force_incremental(orchestration_fixture): + """Run a single generate op and return the force_incremental_flag kwarg + passed to code_generator_main.""" + mock_determine = orchestration_fixture['sync_determine_operation'] + mock_determine.side_effect = [ + SyncDecision(operation='generate', reason='Prompt changed'), + SyncDecision(operation='all_synced', reason='All artifacts are up to date'), + ] + code_path = orchestration_fixture['get_pdd_file_paths'].return_value['code'] + captured = {} + + def fake_codegen(*_args, **_kwargs): + captured['force_incremental_flag'] = _kwargs.get('force_incremental_flag') + code_path.parent.mkdir(parents=True, exist_ok=True) + code_path.write_text("class Calculator:\n pass\n") + return ("class Calculator:\n pass\n", True, 0.10, "model") + + orchestration_fixture['code_generator_main'].side_effect = fake_codegen + return captured + + +def test_generate_defaults_to_surgical_force_incremental(orchestration_fixture): + """Default sync must request edit-shaped (surgical) generation: + code_generator_main receives force_incremental_flag=True.""" + captured = _capture_force_incremental(orchestration_fixture) + + sync_orchestration(basename="calculator", language="python", budget=1.0) + + assert captured['force_incremental_flag'] is True + + +def test_generate_fresh_flag_forces_full_regeneration(orchestration_fixture): + """`pdd sync --fresh` (fresh=True) must restore full-regeneration behavior: + code_generator_main receives force_incremental_flag=False.""" + captured = _capture_force_incremental(orchestration_fixture) + + sync_orchestration(basename="calculator", language="python", budget=1.0, fresh=True) + + assert captured['force_incremental_flag'] is False From 86b6db920d560bf5e49799252f4d26b58004ddd3 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:21:12 -0700 Subject: [PATCH 02/30] docs(agents): enforce prompt-first / back-propagation in agent instructions Add a terse Prompt-First Workflow block near the top of AGENTS.md, CLAUDE.md, and GEMINI.md so coding agents edit prompts first, regenerate with `pdd sync`, run `pdd update --sync-metadata` to back-propagate direct code edits and re-stamp the fingerprint before a PR, never hand-edit `.pdd/meta/*.json` or `architecture.json`, and never delete passing tests. Removes the contradiction where agent docs steered edits into the doctrine's #1 anti-pattern, Prompt Drift. Part of the global-sync program (Issue C). Co-Authored-By: Claude --- AGENTS.md | 7 +++++++ CLAUDE.md | 7 +++++++ GEMINI.md | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 04353b3255..e308dd6a80 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,12 @@ # Repository Guidelines +## Prompt-First Workflow (Read First) +Prompts are the source of truth; code is regenerated from them. This block enforces the doctrine's #1 anti-pattern, Prompt Drift (`docs/prompt-driven-development-doctrine.md` "Anti-Patterns"; `CONTRIBUTING.md` "Core Philosophy"). +- Behavior change: edit `pdd/prompts/_python.prompt` first, regenerate with `pdd sync ` (or `make generate MODULE=`), then adjust tests. +- Edited `pdd/.py` directly (hotfix): run `pdd update --sync-metadata` to back-propagate the change into the prompt and re-stamp the fingerprint BEFORE opening the PR; name the back-propagated units in the PR body. +- Never hand-edit `.pdd/meta/*.json` or `architecture.json`; use `pdd sync-architecture` or the fingerprint stamper (`scripts/stamp_fingerprints.py`). +- Tests accumulate: append tests; never delete passing tests when regenerating. + ## Project Structure & Module Organization Core CLI logic lives in `pdd/`, where each module aligns with a prompt template in `prompts/` (for example, `pdd/code_generator.py` pairs with `prompts/code_generator_python.prompt`). Generated examples drop into `context/`, CSV data into `data/`, and packaged artifacts into `dist/`. Public examples live under `examples/`, and central documentation, diagrams, and onboarding notes reside in `docs/`. diff --git a/CLAUDE.md b/CLAUDE.md index bf4723039c..6e6fb2e13f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,13 @@ This repository contains the public PDD CLI. Keep changes focused on the open-source package and avoid adding private deployment or credential-backed workflow details. +## Prompt-First Workflow (Read First) +Prompts are the source of truth; code is regenerated from them. This block enforces the doctrine's #1 anti-pattern, Prompt Drift (`docs/prompt-driven-development-doctrine.md` "Anti-Patterns"; `CONTRIBUTING.md` "Core Philosophy"). +- Behavior change: edit `pdd/prompts/_python.prompt` first, regenerate with `pdd sync ` (or `make generate MODULE=`), then adjust tests. +- If you edited `pdd/.py` directly (hotfix): run `pdd update --sync-metadata` to back-propagate the change into the prompt and re-stamp the fingerprint BEFORE opening the PR; list the back-propagated units in the PR body. +- Never hand-edit `.pdd/meta/*.json` or `architecture.json`; use `pdd sync-architecture` or the fingerprint stamper (`scripts/stamp_fingerprints.py`). +- Tests accumulate: append tests; never delete passing tests when regenerating. + ## Commands - Install dependencies: `pip install -e ".[dev]"` or `pip install -e .` - Run all tests: `pytest -vv tests/` diff --git a/GEMINI.md b/GEMINI.md index b16e567758..542db9a435 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -4,6 +4,13 @@ This repository contains the public PDD CLI. > **Migration note (Issue #1152):** PDD now supports Google's new Antigravity CLI (`agy`) alongside the legacy Gemini CLI (`gemini`). Both map to the `google` agentic provider. Selection precedence: `PDD_AGENTIC_PROVIDER=antigravity` (pin Antigravity) > `PDD_GOOGLE_CLI=agy|gemini|auto` (binary picker; `auto` prefers `agy` when installed and credentialed, but uses legacy `gemini` when both binaries are installed and the only Google auth signal is `~/.gemini/oauth_creds.json`) > auto-detect. Antigravity can authenticate through OAuth, keyring-backed Google subscription sign-in, `ANTIGRAVITY_API_KEY`/`GOOGLE_API_KEY`, Vertex AI env auth, or PDD's compatibility bridge from `GEMINI_API_KEY`; legacy `gemini` remains the explicit rollback path and uses its own OAuth store or `GEMINI_API_KEY`/`GOOGLE_API_KEY`. Google announced consumer-tier Gemini CLI cutoff on **2026-06-18**. +## Prompt-First Workflow (Read First) +Prompts are the source of truth; code is regenerated from them. This block enforces the doctrine's #1 anti-pattern, Prompt Drift (`docs/prompt-driven-development-doctrine.md` "Anti-Patterns"; `CONTRIBUTING.md` "Core Philosophy"). +- Behavior change: edit `pdd/prompts/_python.prompt` first, regenerate with `pdd sync ` (or `make generate MODULE=`), then adjust tests. +- Edited `pdd/.py` directly (hotfix): run `pdd update --sync-metadata` to back-propagate the change into the prompt and re-stamp the fingerprint BEFORE opening the PR; name the back-propagated units in the PR body. +- Never hand-edit `.pdd/meta/*.json` or `architecture.json`; use `pdd sync-architecture` or the fingerprint stamper (`scripts/stamp_fingerprints.py`). +- Tests accumulate: append tests; never delete passing tests when regenerating. + ## PDD CLI Development - This is a Python CLI tool. From 654d644d5ec7bd44a58f5adf57cbffabf206c0ec Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:21:18 -0700 Subject: [PATCH 03/30] docs(contributing): cross-reference agent prompt-first rules Point Core Philosophy at AGENTS.md/CLAUDE.md/GEMINI.md and the doctrine Anti-Patterns section, and align the "If editing code directly" step with the agent rules (`pdd update --sync-metadata` re-stamp; no hand-editing metadata) so human and agent docs agree and no longer contradict each other. Part of the global-sync program (Issue C). Co-Authored-By: Claude --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5eeaf8716b..f265d371f1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,6 +13,7 @@ Thank you for considering contributing to PDD CLI! This guide summarizes how we - Keep spec/README, prompts, code, examples, and tests in sync. - Tests accumulate: append tests; don’t regenerate or remove them. - Modular prompt graph: prompts compose via includes. +- Coding agents follow the same rules; see `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md`. The #1 doctrine anti‑pattern is Prompt Drift (`docs/prompt-driven-development-doctrine.md`, “Anti‑Patterns”). ## The “Dev Unit” Each complete change ideally includes four elements: @@ -38,7 +39,7 @@ Each complete change ideally includes four elements: 4) Implement - Prefer using PDD to regenerate code from prompts. -- If editing code directly, run `pdd update` to sync changes back into prompts (until all prompts are public, maintainers may help sync). +- If editing code directly, run `pdd update --sync-metadata` to sync changes back into prompts and re‑stamp the fingerprint / reconcile `architecture.json` before opening the PR (until all prompts are public, maintainers may help sync). Never hand‑edit `.pdd/meta/*.json` or `architecture.json`; use `pdd sync-architecture` or the fingerprint stamper (`scripts/stamp_fingerprints.py`). - Keep example interfaces updated to reflect new/changed behavior. - Useful prompt tags when needed: ``, ``, ``, ``. From c166a9766ac6e00bb24a2b8ef599a77316625e64 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:38:20 -0700 Subject: [PATCH 04/30] Backfill 27 missing architecture.json module entries architecture.json is the registry that drives project-wide `pdd sync` (no-arg sync enumerates modules from it via _architecture_sync_modules). 27 top-level pdd/*.py modules that have BOTH a prompt and code were absent, so global sync and dependency-ordered heal were structurally blind to them (construct_paths, load_prompt_template, config_resolution, cli_theme, one_session_sync, provider_manager, reasoning, edit_file, ...). Entries are appended (no reflow of existing bytes) with: - reason: prompt tag, else module docstring first sentence - description: module docstring first paragraph, else prompt reason - interface: derived from code AST (public classes + functions with signatures/returns), mirroring the existing module-interface schema - dependencies: the prompt's own / declarations only, so `pdd checkup --validate-arch-includes` stays green (import-derived deps would register as declaration drift and fail that gate) - priority: max(existing)+1..; tags: []; position omitted (54 entries omit it) Coverage of top-level pdd modules: 152 -> 179. Sync enumeration: 188 -> 215. Co-Authored-By: Claude --- architecture.json | 1098 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1098 insertions(+) diff --git a/architecture.json b/architecture.json index fbbc3de48c..4fbbf40d8d 100644 --- a/architecture.json +++ b/architecture.json @@ -11802,5 +11802,1103 @@ ] } } + }, + { + "reason": "Discovers API keys needed by the user's configured models, checking existence across shell, .env, and PDD config with source transparency.", + "description": "Discovers API keys needed by the user's configured models, checking existence across shell, .env, and PDD config with source transparency.", + "dependencies": [], + "priority": 251, + "filename": "api_key_scanner_python.prompt", + "filepath": "pdd/api_key_scanner.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "KeyInfo", + "kind": "dataclass" + } + ], + "functions": [ + { + "name": "get_provider_key_names", + "signature": "() -> List[str]", + "returns": "List[str]" + }, + { + "name": "scan_environment", + "signature": "() -> Dict[str, KeyInfo]", + "returns": "Dict[str, KeyInfo]" + } + ] + } + } + }, + { + "reason": "Cross-validate architecture.json dependency entries against tags in prompts.", + "description": "Cross-validate architecture.json dependency entries against tags in prompts.", + "dependencies": [], + "priority": 252, + "filename": "architecture_include_validation_python.prompt", + "filepath": "pdd/architecture_include_validation.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "collect_architecture_include_validation_warnings", + "signature": "(project_root: Path, *, skip_bundled_sample_arch: bool = True) -> List[str]", + "returns": "List[str]" + }, + { + "name": "run_validate_arch_includes_cli", + "signature": "(project_root: Path, *, strict: bool, quiet: bool) -> None", + "returns": "None" + }, + { + "name": "list_validate_arch_include_warnings", + "signature": "(project_root: Path, *, strict: bool) -> List[str]", + "returns": "List[str]" + }, + { + "name": "print_architecture_include_validation_warnings", + "signature": "(*, quiet: bool, verbose: bool = False) -> None", + "returns": "None" + }, + { + "name": "resolve_architecture_prompt_path", + "signature": "(filename: str, project_root: Path) -> Path", + "returns": "Path" + }, + { + "name": "validate_prompt_contract_context", + "signature": "(prompt_path: Path, output_path: Path, project_root: Path, architecture_path: Optional[Path] = None, prompt_content: Optional[str] = None, require_prompt_local_source_context: bool = False) -> List[str]", + "returns": "List[str]" + }, + { + "name": "cross_validate_architecture_with_prompt_includes", + "signature": "(arch_data: List[Dict[str, Any]], project_root: Path) -> List[str]", + "returns": "List[str]" + } + ] + } + } + }, + { + "reason": "Update architecture.json dependencies after auto-deps inserts new module tags.", + "description": "Update architecture.json dependencies after auto-deps inserts new module tags.", + "dependencies": [], + "priority": 253, + "filename": "auto_deps_architecture_python.prompt", + "filepath": "pdd/auto_deps_architecture.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "extract_include_paths_from_prompt_text", + "signature": "(text: str) -> Set[str]", + "returns": "Set[str]" + }, + { + "name": "merge_auto_deps_includes_into_architecture", + "signature": "(project_root: Path, written_prompt_path: Path, old_prompt_text: str, new_prompt_text: str, *, dry_run: bool = False) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + }, + { + "name": "merge_auto_deps_includes_from_cwd", + "signature": "(written_prompt_path: Path, old_prompt_text: str, new_prompt_text: str, *, dry_run: bool = False) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + } + ] + } + } + }, + { + "reason": "Detect PDD module basenames affected by a git diff.", + "description": "Detect PDD module basenames affected by a git diff.", + "dependencies": [], + "priority": 254, + "filename": "ci_detect_changed_modules_python.prompt", + "filepath": "pdd/ci_detect_changed_modules.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "detect", + "signature": "(diff_base: str) -> list[str]", + "returns": "list[str]" + }, + { + "name": "main", + "signature": "() -> int", + "returns": "int" + } + ] + } + } + }, + { + "reason": "Centralizes PDD CLI status progress messaging so every command reports start, current step, waiting-on-IO/LLM, success, and failure with one consistent, skimmable, non-duplicative, brand-themed vocabulary instead of ad-hoc per-module prints.", + "description": "Consistent status & progress messaging for the PDD CLI.", + "dependencies": [], + "priority": 255, + "filename": "cli_status_python.prompt", + "filepath": "pdd/cli_status.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "Status", + "kind": "enum" + }, + { + "name": "StatusMessage", + "kind": "dataclass" + }, + { + "name": "StatusReporter", + "kind": "class" + } + ], + "functions": [ + { + "name": "StatusMessage.glyph", + "signature": "(self) -> str", + "returns": "str" + }, + { + "name": "StatusMessage.role", + "signature": "(self) -> str", + "returns": "str" + }, + { + "name": "StatusMessage.render_plain", + "signature": "(self) -> str", + "returns": "str" + }, + { + "name": "StatusMessage.render_markup", + "signature": "(self) -> str", + "returns": "str" + }, + { + "name": "StatusReporter.emit", + "signature": "(self, message: StatusMessage) -> StatusMessage", + "returns": "StatusMessage" + }, + { + "name": "StatusReporter.start", + "signature": "(self, text: str, *, next_step: Optional[str] = None) -> StatusMessage", + "returns": "StatusMessage" + }, + { + "name": "StatusReporter.step", + "signature": "(self, text: str) -> StatusMessage", + "returns": "StatusMessage" + }, + { + "name": "StatusReporter.success", + "signature": "(self, text: str, *, next_step: Optional[str] = None) -> StatusMessage", + "returns": "StatusMessage" + }, + { + "name": "StatusReporter.failure", + "signature": "(self, text: str, *, reason: Optional[str] = None, suggestions: Sequence[str] = ()) -> StatusMessage", + "returns": "StatusMessage" + }, + { + "name": "StatusReporter.waiting", + "signature": "(self, text: str, *, on: str = 'LLM') -> Iterator[StatusMessage]", + "returns": "Iterator[StatusMessage]" + }, + { + "name": "from_context", + "signature": "(ctx, command: Optional[str] = None) -> StatusReporter", + "returns": "StatusReporter" + } + ] + } + } + }, + { + "reason": "Centralizes the PDD CLI color system so every command renders commands, tags, labels, and states with one consistent, brand-derived palette instead of ad-hoc per-module colors.", + "description": "Central CLI color system for PDD.", + "dependencies": [], + "priority": 256, + "filename": "cli_theme_python.prompt", + "filepath": "pdd/cli_theme.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "apply_global_color_preference", + "signature": "(preference: Optional[bool]) -> Callable[[], None]", + "returns": "Callable[[], None]" + }, + { + "name": "hex_to_ansi", + "signature": "(hex_color: str) -> str", + "returns": "str" + }, + { + "name": "get_console", + "signature": "(**kwargs) -> Console", + "returns": "Console" + }, + { + "name": "style", + "signature": "(role: str, text: str) -> str", + "returns": "str" + } + ] + } + } + }, + { + "reason": "Centralized config resolution for all commands, ensuring consistent priority ordering.", + "description": "Centralized config resolution for all commands.", + "dependencies": [], + "priority": 257, + "filename": "config_resolution_python.prompt", + "filepath": "pdd/config_resolution.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "set_cli_compression_override", + "signature": "(cli_config: Optional[Dict[str, Any]]) -> None", + "returns": "None" + }, + { + "name": "merge_cli_compression_override", + "signature": "(additional: Dict[str, Any]) -> None", + "returns": "None" + }, + { + "name": "get_cli_compression_override", + "signature": "() -> Optional[Dict[str, Any]]", + "returns": "Optional[Dict[str, Any]]" + }, + { + "name": "effective_compression_config", + "signature": "(pddrc_config: Dict[str, Any]) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + }, + { + "name": "apply_compression_env", + "signature": "(config: Dict[str, Any]) -> None", + "returns": "None" + }, + { + "name": "resolve_effective_config", + "signature": "(ctx: click.Context, resolved_config: Dict[str, Any], param_overrides: Optional[Dict[str, Any]] = None) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + } + ] + } + } + }, + { + "reason": "Detects and reports conflicts within prompt files.", + "description": "Detects and reports conflicts within prompt files.", + "dependencies": [], + "priority": 258, + "filename": "conflicts_in_prompts_python.prompt", + "filepath": "pdd/conflicts_in_prompts.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "ConflictChange", + "kind": "class" + }, + { + "name": "ConflictResponse", + "kind": "class" + } + ], + "functions": [ + { + "name": "conflicts_in_prompts", + "signature": "(prompt1: str, prompt2: str, strength: float = DEFAULT_STRENGTH, temperature: float = 0, time: float = DEFAULT_TIME, verbose: bool = False) -> Tuple[List[dict], float, str]", + "returns": "Tuple[List[dict], float, str]" + }, + { + "name": "main", + "signature": "()" + } + ] + } + } + }, + { + "reason": "Resolves configuration, validates input files, and determines output paths.", + "description": "Resolves configuration, validates input files, and determines output paths.", + "dependencies": [], + "priority": 259, + "filename": "construct_paths_python.prompt", + "filepath": "pdd/construct_paths.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "list_available_contexts", + "signature": "(start_path: Optional[Path] = None) -> list[str]", + "returns": "list[str]" + }, + { + "name": "detect_context_for_file", + "signature": "(file_path: str, repo_root: Optional[str] = None) -> Tuple[Optional[str], Dict[str, Any]]", + "returns": "Tuple[Optional[str], Dict[str, Any]]" + }, + { + "name": "resolve_effective_config", + "signature": "(*, cli_options: Optional[Dict[str, Any]] = None, context_override: Optional[str] = None, cwd: Optional[Path] = None, prompt_file: Optional[str] = None, basename_hint: Optional[str] = None, quiet: bool = False) -> Tuple[Optional[str], Optional[Path], Dict[str, Any], Dict[str, Any], Dict[str, Any]]", + "returns": "Tuple[Optional[str], Optional[Path], Dict[str, Any], Dict[str, Any], Dict[str, Any]]" + }, + { + "name": "get_tests_dir_from_config", + "signature": "(start_path: Optional[Path] = None) -> Optional[Path]", + "returns": "Optional[Path]" + }, + { + "name": "get_language_outputs", + "signature": "(language_name: str) -> set[str]", + "returns": "set[str]" + }, + { + "name": "construct_paths", + "signature": "(input_file_paths: Dict[str, str], force: bool, quiet: bool, command: str, command_options: Optional[Dict[str, Any]], create_error_file: bool = True, context_override: Optional[str] = None, confirm_callback: Optional[Callable[[str, str], bool]] = None, path_resolution_mode: Optional[str] = None) -> Tuple[Dict[str, Any], Dict[str, str], Dict[str, str], str]", + "returns": "Tuple[Dict[str, Any], Dict[str, str], Dict[str, str], str]" + } + ] + } + } + }, + { + "reason": "File editor module that uses Claude 3.7 to edit files based on natural language instructions.", + "description": "File editor module that uses Claude 3.7 to edit files based on natural language instructions.", + "dependencies": [], + "priority": 260, + "filename": "edit_file_python.prompt", + "filepath": "pdd/edit_file.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "EditFileState", + "kind": "class" + } + ], + "functions": [ + { + "name": "calculate_hash", + "signature": "(content: str) -> str", + "returns": "str" + }, + { + "name": "read_file_content", + "signature": "(file_path: str) -> tuple[Optional[str], Optional[str]]", + "returns": "tuple[Optional[str], Optional[str]]" + }, + { + "name": "write_file_content", + "signature": "(file_path: str, content: str) -> bool", + "returns": "bool" + }, + { + "name": "start_editing", + "signature": "(state: EditFileState) -> EditFileState", + "returns": "EditFileState" + }, + { + "name": "format_tools_for_claude", + "signature": "(tools)" + }, + { + "name": "plan_edits", + "signature": "(state: EditFileState) -> EditFileState", + "returns": "EditFileState" + }, + { + "name": "execute_edit", + "signature": "(state: EditFileState) -> EditFileState", + "returns": "EditFileState" + }, + { + "name": "handle_error", + "signature": "(state: EditFileState) -> EditFileState", + "returns": "EditFileState" + }, + { + "name": "decide_next_step", + "signature": "(state: EditFileState) -> Literal['execute_edit', 'handle_error', END]", + "returns": "Literal['execute_edit', 'handle_error', END]" + }, + { + "name": "check_edit_result", + "signature": "(state: EditFileState) -> Literal['plan_edits', 'handle_error']", + "returns": "Literal['plan_edits', 'handle_error']" + }, + { + "name": "edit_file", + "signature": "(file_path: str, edit_instructions: str, mcp_config_path: str = None) -> tuple[bool, Optional[str]]", + "returns": "tuple[bool, Optional[str]]" + }, + { + "name": "main", + "signature": "()" + }, + { + "name": "run_edit_in_subprocess", + "signature": "(file_path: str, edit_instructions: str) -> Tuple[bool, Optional[str]]", + "returns": "Tuple[bool, Optional[str]]" + } + ] + } + } + }, + { + "reason": "CLI subcommand that garbage-collects orphaned .pdd/extracts/ entries not referenced by any prompt.", + "description": "CLI commands for managing the .pdd/extracts/ directory.", + "dependencies": [ + "include_query_extractor_python.prompt", + "path_resolution_python.prompt", + "preprocess_python.prompt" + ], + "priority": 261, + "filename": "extracts_prune_python.prompt", + "filepath": "pdd/extracts_prune.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "parse_include_tags", + "signature": "(text: str) -> list[tuple[str, str]]", + "returns": "list[tuple[str, str]]" + }, + { + "name": "extracts", + "signature": "()" + }, + { + "name": "prune", + "signature": "(ctx: click.Context, force: bool) -> None", + "returns": "None" + } + ] + } + } + }, + { + "reason": "Persistent Firecrawl scrape cache using SQLite with TTL, URL normalization, and LRU cleanup.", + "description": "Firecrawl caching module for PDD.", + "dependencies": [], + "priority": 262, + "filename": "firecrawl_cache_python.prompt", + "filepath": "pdd/firecrawl_cache.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "FirecrawlCache", + "kind": "class" + } + ], + "functions": [ + { + "name": "FirecrawlCache.get", + "signature": "(self, url: str) -> Optional[str]", + "returns": "Optional[str]" + }, + { + "name": "FirecrawlCache.set", + "signature": "(self, url: str, content: str, ttl_hours: Optional[int] = None, metadata: Optional[Dict[str, Any]] = None) -> bool", + "returns": "bool" + }, + { + "name": "FirecrawlCache.clear", + "signature": "(self) -> int", + "returns": "int" + }, + { + "name": "FirecrawlCache.get_stats", + "signature": "(self) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + }, + { + "name": "get_firecrawl_cache", + "signature": "() -> FirecrawlCache", + "returns": "FirecrawlCache" + }, + { + "name": "clear_firecrawl_cache", + "signature": "() -> int", + "returns": "int" + }, + { + "name": "get_firecrawl_cache_stats", + "signature": "() -> dict", + "returns": "dict" + } + ] + } + } + }, + { + "reason": "Fixes a failing code module and its calling program using an LLM, given the prompt, code, and captured errors.", + "description": "Fixes a failing code module and its calling program using an LLM, given the prompt, code, and captured errors.", + "dependencies": [], + "priority": 263, + "filename": "fix_code_module_errors_python.prompt", + "filepath": "pdd/fix_code_module_errors.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "CodeFix", + "kind": "class" + } + ], + "functions": [ + { + "name": "validate_inputs", + "signature": "(program: str, prompt: str, code: str, errors: str, strength: float) -> None", + "returns": "None" + }, + { + "name": "fix_code_module_errors", + "signature": "(program: str, prompt: str, code: str, errors: str, strength: float = DEFAULT_STRENGTH, temperature: float = 0, time: float = DEFAULT_TIME, verbose: bool = False, program_path: str = '', code_path: str = '') -> Tuple[bool, bool, str, str, str, float, str]", + "returns": "Tuple[bool, bool, str, str, str, float, str]" + } + ] + } + } + }, + { + "reason": "Deterministic completion checks for provider-finished generations.", + "description": "Deterministic completion checks for provider-finished generations.", + "dependencies": [], + "priority": 264, + "filename": "generation_completion_python.prompt", + "filepath": "pdd/generation_completion.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "completion_check_tail", + "signature": "(text: str, max_chars: int = 600) -> str", + "returns": "str" + }, + { + "name": "provider_reports_completion", + "signature": "(finish_reason: Any) -> bool", + "returns": "bool" + }, + { + "name": "provider_finished_structurally", + "signature": "(output: Any, finish_reason: Any, language: str) -> bool", + "returns": "bool" + }, + { + "name": "output_is_structurally_complete", + "signature": "(output: str, language: str) -> bool", + "returns": "bool" + }, + { + "name": "strip_outer_code_fence", + "signature": "(output: str) -> Tuple[str, bool]", + "returns": "Tuple[str, bool]" + }, + { + "name": "python_code_parses", + "signature": "(code: str) -> bool", + "returns": "bool" + }, + { + "name": "json_parses", + "signature": "(text: str) -> bool", + "returns": "bool" + } + ] + } + } + }, + { + "reason": "Module to retrieve file extensions for programming languages.", + "description": "Module to retrieve file extensions for programming languages.", + "dependencies": [], + "priority": 265, + "filename": "get_extension_python.prompt", + "filepath": "pdd/get_extension.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "get_extension", + "signature": "(language: str) -> str", + "returns": "str" + } + ] + } + } + }, + { + "reason": "Module to retrieve run commands for programming languages.", + "description": "Module to retrieve run commands for programming languages.", + "dependencies": [], + "priority": 266, + "filename": "get_run_command_python.prompt", + "filepath": "pdd/get_run_command.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "get_run_command", + "signature": "(extension: str) -> str", + "returns": "str" + }, + { + "name": "get_run_command_for_file", + "signature": "(file_path: str) -> str", + "returns": "str" + } + ] + } + } + }, + { + "reason": "Handles semantic extraction from files using LLMs with persistent caching for reproducibility.", + "description": "Semantic extraction from files using LLMs with persistent caching.", + "dependencies": [ + "llm_invoke_python.prompt", + "load_prompt_template_python.prompt", + "path_resolution_python.prompt", + "preprocess_python.prompt" + ], + "priority": 267, + "filename": "include_query_extractor_python.prompt", + "filepath": "pdd/include_query_extractor.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "RepeatedRetrievalQueryError", + "kind": "class" + }, + { + "name": "IncludeQueryExtractor", + "kind": "class" + } + ], + "functions": [ + { + "name": "compute_cache_key", + "signature": "(source_file_path: str, query: str) -> str", + "returns": "str" + }, + { + "name": "IncludeQueryExtractor.reset_session", + "signature": "(cls) -> None", + "returns": "None" + }, + { + "name": "IncludeQueryExtractor.extract", + "signature": "(self, file_path: str, query: str) -> str", + "returns": "str" + } + ] + } + } + }, + { + "reason": "Loads and caches prompt templates from the prompts directory.", + "description": "Loads and caches prompt templates from the prompts directory.", + "dependencies": [], + "priority": 268, + "filename": "load_prompt_template_python.prompt", + "filepath": "pdd/load_prompt_template.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "print_formatted", + "signature": "(message: str) -> None", + "returns": "None" + }, + { + "name": "load_prompt_template", + "signature": "(prompt_name: str) -> Optional[str]", + "returns": "Optional[str]" + } + ] + } + } + }, + { + "reason": "Tests individual models via litellm.completion() with direct API key passing and diagnostics.", + "description": "Tests individual models via litellm.completion() with direct API key passing and diagnostics.", + "dependencies": [], + "priority": 269, + "filename": "model_tester_python.prompt", + "filepath": "pdd/model_tester.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "test_model_interactive", + "signature": "() -> None", + "returns": "None" + } + ] + } + } + }, + { + "reason": "Runs example generation, crash-fix, verify, test generation, and test-fix steps in a single agentic session instead of sequential sync/fix/test calls.", + "description": "One-session sync: run example, crash-fix, verify, test, and fix steps in a single agentic session instead of separate sessions per step.", + "dependencies": [ + "code_generator_main_python.prompt", + "fix_code_loop_python.prompt", + "fix_error_loop_python.prompt", + "fix_verification_errors_loop_python.prompt", + "generate_test_python.prompt" + ], + "priority": 270, + "filename": "one_session_sync_python.prompt", + "filepath": "pdd/one_session_sync.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "build_one_session_prompt", + "signature": "(basename: str, language: str, pdd_files: Dict[str, Path], project_root: Path, *, target_coverage: float = 90.0) -> str", + "returns": "str" + }, + { + "name": "run_one_session_sync", + "signature": "(basename: str, language: str, pdd_files: Dict[str, Path], project_root: Path, *, target_coverage: float = 90.0, budget: Optional[float] = None, verbose: bool = False, quiet: bool = False, timeout: Optional[float] = None) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + } + ] + } + } + }, + { + "reason": "Creates and auto-generates .pddrc configuration files with sensible defaults, including multi-context support for monorepos.", + "description": "Creates and auto-generates .pddrc configuration files with sensible defaults, including multi-context support for monorepos.", + "dependencies": [], + "priority": 271, + "filename": "pddrc_initializer_python.prompt", + "filepath": "pdd/pddrc_initializer.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "offer_pddrc_init", + "signature": "() -> bool", + "returns": "bool" + }, + { + "name": "infer_contexts_from_scan", + "signature": "(scan_dir: str, repo_root: str, code_files: List[str]) -> Dict[str, Dict]", + "returns": "Dict[str, Dict]" + }, + { + "name": "ensure_pddrc_for_scan", + "signature": "(scan_dir: str, repo_root: str, code_files: List[str], quiet: bool = False) -> Optional[Path]", + "returns": "Optional[Path]" + } + ] + } + } + }, + { + "reason": "Orchestrates the complete PDD sync workflow by coordinating operations and animations in parallel, serving as the core engine for the `pdd sync` command.", + "description": "Orchestrates the complete PDD sync workflow by coordinating operations and animations in parallel, serving as the core engine for the `pdd sync` command.", + "dependencies": [], + "priority": 272, + "filename": "pin_example_hack_python.prompt", + "filepath": "pdd/pin_example_hack.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "classes": [ + { + "name": "PendingStateUpdate", + "kind": "dataclass" + }, + { + "name": "AtomicStateUpdate", + "kind": "class" + } + ], + "functions": [ + { + "name": "AtomicStateUpdate.set_run_report", + "signature": "(self, report: Dict[str, Any], path: Path)" + }, + { + "name": "AtomicStateUpdate.set_fingerprint", + "signature": "(self, fingerprint: Dict[str, Any], path: Path)" + }, + { + "name": "load_sync_log", + "signature": "(basename: str, language: str) -> List[Dict[str, Any]]", + "returns": "List[Dict[str, Any]]" + }, + { + "name": "create_sync_log_entry", + "signature": "(decision, budget_remaining: float) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + }, + { + "name": "update_sync_log_entry", + "signature": "(entry: Dict[str, Any], result: Dict[str, Any], duration: float) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + }, + { + "name": "append_sync_log", + "signature": "(basename: str, language: str, entry: Dict[str, Any])" + }, + { + "name": "log_sync_event", + "signature": "(basename: str, language: str, event: str, details: Dict[str, Any] = None)" + }, + { + "name": "save_run_report", + "signature": "(report: Dict[str, Any], basename: str, language: str, atomic_state: Optional['AtomicStateUpdate'] = None)" + }, + { + "name": "sync_orchestration", + "signature": "(basename: str, target_coverage: float = 90.0, language: str = 'python', prompts_dir: str = 'prompts', code_dir: str = 'src', examples_dir: str = 'examples', tests_dir: str = 'tests', max_attempts: int = 3, budget: float = 10.0, skip_verify: bool = False, skip_tests: bool = False, dry_run: bool = False, force: bool = False, strength: float = DEFAULT_STRENGTH, temperature: float = 0.0, time_param: float = 0.25, verbose: bool = False, quiet: bool = False, output_cost: Optional[str] = None, review_examples: bool = False, local: bool = False, context_config: Optional[Dict[str, str]] = None, context_override: Optional[str] = None, confirm_callback: Optional[Callable[[str, str], bool]] = None) -> Dict[str, Any]", + "returns": "Dict[str, Any]" + } + ] + } + } + }, + { + "reason": "Manages LLM providers: browse reference CSV to add models, custom providers, and model removal with shell-aware credential storage.", + "description": "Manages LLM providers: browse reference CSV to add models, custom providers, and model removal with shell-aware credential storage.", + "dependencies": [ + "api_key_scanner_python.prompt" + ], + "priority": 273, + "filename": "provider_manager_python.prompt", + "filepath": "pdd/provider_manager.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "parse_api_key_vars", + "signature": "(api_key_field: str) -> List[str]", + "returns": "List[str]" + }, + { + "name": "api_key_aliases", + "signature": "(key_name: str) -> List[str]", + "returns": "List[str]" + }, + { + "name": "expand_api_key_vars", + "signature": "(api_key_field: str) -> List[str]", + "returns": "List[str]" + }, + { + "name": "api_key_requirements_satisfied", + "signature": "(api_key_field: str, configured_key_names: Iterable[str]) -> bool", + "returns": "bool" + }, + { + "name": "resolve_api_key_from_env", + "signature": "(key_name: str, env: Optional[Dict[str, str]] = None, *, include_llm_invoke_aliases: bool = False) -> Tuple[Optional[str], Optional[str]]", + "returns": "Tuple[Optional[str], Optional[str]]" + }, + { + "name": "preferred_api_key_name", + "signature": "(key_name: str) -> str", + "returns": "str" + }, + { + "name": "is_multi_credential", + "signature": "(api_key_field: str) -> bool", + "returns": "bool" + }, + { + "name": "add_provider_from_registry", + "signature": "() -> bool", + "returns": "bool" + }, + { + "name": "add_custom_provider", + "signature": "() -> bool", + "returns": "bool" + }, + { + "name": "remove_models_by_provider", + "signature": "() -> bool", + "returns": "bool" + }, + { + "name": "remove_individual_models", + "signature": "() -> bool", + "returns": "bool" + } + ] + } + } + }, + { + "reason": "Python Environment Detector", + "description": "Python Environment Detector", + "dependencies": [], + "priority": 274, + "filename": "python_env_detector_python.prompt", + "filepath": "pdd/python_env_detector.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "detect_host_python_executable", + "signature": "() -> str", + "returns": "str" + }, + { + "name": "get_environment_info", + "signature": "() -> dict", + "returns": "dict" + }, + { + "name": "is_in_virtual_environment", + "signature": "() -> bool", + "returns": "bool" + }, + { + "name": "get_environment_type", + "signature": "() -> str", + "returns": "str" + } + ] + } + } + }, + { + "reason": "Shared helpers for mapping --time floats to provider reasoning effort.", + "description": "Shared helpers for mapping --time floats to provider reasoning effort.", + "dependencies": [], + "priority": 275, + "filename": "reasoning_python.prompt", + "filepath": "pdd/reasoning.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "time_to_effort_level", + "signature": "(time: float) -> EffortLevel", + "returns": "EffortLevel" + } + ] + } + } + }, + { + "reason": "Utility for expanding path templates with dynamic placeholders for project layout generation.", + "description": "Template expansion utility for output path configuration.", + "dependencies": [], + "priority": 276, + "filename": "template_expander_python.prompt", + "filepath": "pdd/template_expander.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "expand_template", + "signature": "(template: str, context: Dict[str, Any]) -> str", + "returns": "str" + } + ] + } + } + }, + { + "reason": "Utilities for validating and cleaning tags in generated prompt content.", + "description": "Utilities for validating and cleaning tags in generated prompt content.", + "dependencies": [], + "priority": 277, + "filename": "validate_prompt_includes_python.prompt", + "filepath": "pdd/validate_prompt_includes.py", + "tags": [], + "interface": { + "type": "module", + "module": { + "functions": [ + { + "name": "validate_include_tag", + "signature": "(file_path: str, base_dir: str) -> bool", + "returns": "bool" + }, + { + "name": "validate_prompt_includes", + "signature": "(content: str, base_dir: str | Path = '.', remove_invalid: bool = False) -> Tuple[str, List[str]]", + "returns": "Tuple[str, List[str]]" + }, + { + "name": "sanitize_prompt_output", + "signature": "(content: str, output_path: str | Path) -> Tuple[str, List[str]]", + "returns": "Tuple[str, List[str]]" + } + ] + } + } } ] From bc82c8b19a6000cd06f69be48f382f680a8b25d6 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:38:35 -0700 Subject: [PATCH 05/30] Drop phantom load_prompt_template dep from agentic_test_orchestrator entry Registering load_prompt_template (previous commit) surfaced a latent inconsistency: agentic_test_orchestrator's architecture entry listed load_prompt_template_python.prompt as a dependency, but its prompt only references load_prompt_template via a context-example include (context/load_prompt_template_example.py), never via or a module-prompt . Per the validator's own model (context/example artifacts are not module dependencies), that dependency edge is spurious; it stayed invisible only because load_prompt_template had no entry to map to. Removing it keeps `pdd checkup --validate-arch-includes` green (0 -> 0 non-strict warnings). If maintainers consider it a real module dependency, the alternative fix is a prompt-side declaration (prompts are out of scope for this change). Co-Authored-By: Claude --- architecture.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/architecture.json b/architecture.json index 4fbbf40d8d..28f8099c03 100644 --- a/architecture.json +++ b/architecture.json @@ -6917,8 +6917,7 @@ "reason": "Orchestrates the 18-step agentic test workflow with exploratory testing and plan validation.", "description": "Coordinates duplicate checking, docs review, clarification, frontend detection, test planning, plan enhancement, coverage assessment, manual testing, regression tests, test generation, plan validation, and PR submission.", "dependencies": [ - "agentic_common_python.prompt", - "load_prompt_template_python.prompt" + "agentic_common_python.prompt" ], "priority": 196, "filename": "agentic_test_orchestrator_python.prompt", From ebf4b90647d0559334abeee9897ad57caf3ca9ce Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:48:35 -0700 Subject: [PATCH 06/30] Add architecture.json completeness bijection gate + waiver file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tests/test_architecture_completeness.py asserts a module<->entry bijection: every top-level pdd/*.py module (after .pddignore) has exactly one architecture.json entry, unless waived in architecture_waivers.json. Also checks every entry's filepath (code) and filename (prompt) exist on disk, and ratchets the adjacent orphan gaps (prompt-no-code, code-no-prompt, code-no-test) so new gaps must be documented, not silent. Two meta-tests prove the gate has teeth (a removed entry / an unwaived new module both fail it). architecture_waivers.json documents: - modules_without_architecture_entry: 20 hand-written utilities / CLI wiring with no generating prompt (json_atomic, drift_main, __main__, ...), each with a one-line reason — these are exempt from the bijection. - orphans.{prompt_without_code(16), code_without_prompt(21), code_without_test(22)} - known_registry_exceptions: 2 pre-existing double-registrations (user_story_tests, coverage_contracts; merged by sync at runtime) and 2 entries predating the description field, documented for ratchet-down. Reuses pdd's own helpers (_load_pddignore/_is_pddignored, extract_modules, _basename_from_architecture_filename) so the gate tracks production semantics. Co-Authored-By: Claude --- architecture_waivers.json | 105 +++++++++ tests/test_architecture_completeness.py | 280 ++++++++++++++++++++++++ 2 files changed, 385 insertions(+) create mode 100644 architecture_waivers.json create mode 100644 tests/test_architecture_completeness.py diff --git a/architecture_waivers.json b/architecture_waivers.json new file mode 100644 index 0000000000..a3d39362d1 --- /dev/null +++ b/architecture_waivers.json @@ -0,0 +1,105 @@ +{ + "_README": "Waiver + orphan tracking for architecture.json completeness. Consumed by tests/test_architecture_completeness.py, which asserts a module<->entry bijection: every top-level pdd/*.py module (after .pddignore) has exactly one architecture.json entry UNLESS it is listed in 'modules_without_architecture_entry'. The 'orphans' sections are visibility/ratchet tracking (prompt-no-code, code-no-prompt, code-no-test) so these gaps are explicit, not silent. Keep this file exact: adding/removing a module, prompt, or test without updating the relevant list fails the test with an actionable diff. To clear a waiver, add the missing architecture entry (pdd sync-architecture / author it) and delete the line here.", + "version": 1, + "known_registry_exceptions": { + "_README": "Pre-existing architecture.json data-quality issues that predate this gate. Documented (not fixed) so the gate is green on main while still failing on NEW occurrences. Ratchet these down over time.", + "duplicate_filepaths": { + "pdd/user_story_tests.py": "Pre-existing double-registration (two entries, priority 6 and 241, same filename/filepath). Tolerated by sync (_architecture_sync_modules merges duplicates by output path). TODO: dedupe to a single entry.", + "pdd/coverage_contracts.py": "Pre-existing double-registration (two entries, priority 6 and 241, same filename/filepath). Tolerated by sync (merged by output path). TODO: dedupe to a single entry." + }, + "entries_without_description": { + "test_context_packer_python.prompt": "Pre-existing entry predating the 'description' field convention. TODO: add a description.", + "compressed_sync_context_python.prompt": "Pre-existing entry predating the 'description' field convention. TODO: add a description." + } + }, + "modules_without_architecture_entry": { + "__main__": "Package entry point for `python -m pdd`; thin CLI shim, not a prompt-generated unit.", + "_selector_parse": "Private leaf helper (underscore) for parsing include `select` attributes; no standalone prompt.", + "architecture_sync_helper": "Hand-written filename-normalization helper for architecture_sync; no standalone prompt.", + "checkup_target": "Deterministic `pdd checkup` target classifier; hand-written, no generating prompt.", + "compression_reporting": "Deterministic context-compression reporting helper (#877); hand-written, no prompt.", + "context_snapshot_policy": "Deterministic policy checks for snapshotted prompt context; hand-written, no prompt.", + "continuous_sync": "Deterministic continuous-sync classification/reconciliation reporting; hand-written, no prompt.", + "drift_main": "CLI entry wiring for `pdd checkup drift`; hand-written `_main`, no generating prompt.", + "grounding_provenance": "Shared grounding-metadata helpers for llm_invoke/evidence manifests; hand-written leaf, no prompt.", + "interface_semantics": "Deterministic interface-conformance helpers; hand-written, no prompt.", + "json_atomic": "Dependency-light atomic JSON write utility (guards architecture.json); hand-written leaf, no prompt.", + "json_invocation": "Dependency-light leaf detecting JSON-only CLI invocations; hand-written, no prompt.", + "language_extensions": "Canonical file-extension source-of-truth table; hand-written leaf, no prompt.", + "list_drift_detection": "Deterministic hardcoded-list-vs-canonical drift detector (pdd_cloud#1405); hand-written, no prompt.", + "prompt_gate": "Prompt-quality gate config/workflow hooks; hand-written, no generating prompt.", + "source_set_model": "Deterministic resolver of prompt-shaped checkup targets to `.prompt` paths; hand-written, no prompt.", + "story_test_generation": "Deterministic pytest generator from user-story files; hand-written, no prompt.", + "sync_graph_order_consistency": "Deterministic architecture.json-vs- sync-order consistency detector; hand-written, no prompt.", + "test_result": "Shared return-type dataclass for test-generation commands (#1072); hand-written leaf, no prompt.", + "waiver_policy": "Shared waiver-status classification helpers; hand-written leaf, no prompt." + }, + "orphans": { + "_README": "Informational tracking of adjacent gaps. These do NOT need architecture.json entries; they are listed so the gaps are visible and can be ratcheted down.", + "prompt_without_code": { + "Makefile": "Makefile_makefile.prompt generates the repo Makefile; output is not a pdd/*.py module.", + "core_dump_smoke": "core_dump_smoke_python.prompt is a smoke-test fixture (trivial add()); not a real module.", + "gate": "gate_python.prompt/gate_policy_python.prompt; code lives at pdd/commands/gate.py (CLI command), not top-level pdd/gate.py.", + "language_format": "language_format_csv.prompt generates a language data table (CSV); not a pdd/*.py module.", + "llm_model": "llm_model_csv.prompt generates the LLM model reference (CSV); not a pdd/*.py module.", + "main_gen_prompt": "Meta-prompt that generates prompt text; emits a prompt, not a pdd/*.py module.", + "pdd_completion": "pdd_completion_{bash,fish,zsh}.prompt generate shell-completion scripts; not a pdd/*.py module.", + "pdd_theme": "pdd_theme_json.prompt generates theme reference data (JSON); theme code is pdd/cli_theme.py.", + "prompt_tester": "prompt_tester_python.prompt has no committed pdd/prompt_tester.py (standalone tool). TODO justify/reconcile.", + "pypi_description": "pypi_description_restructuredtext.prompt generates the PyPI long description (rST); not a pdd/*.py module.", + "pyproject": "pyproject_toml.prompt generates pyproject.toml; not a pdd/*.py module.", + "regression": "regression_bash.prompt generates the regression harness script; not a pdd/*.py module.", + "regression_analysis": "regression_analysis_log.prompt emits regression analysis text; not a pdd/*.py module.", + "resurface_check": "resurface_check_Python.prompt is a pdd_cloud Rising Stars Cloud Function; code lives in the pdd_cloud repo, not here.", + "run_generated": "run_generated_python.prompt has no committed pdd/run_generated.py. TODO justify/reconcile.", + "task_routing": "task_routing_csv.prompt generates routing config (CSV); not a pdd/*.py module." + }, + "code_without_prompt": { + "__main__": "Package entry point; see modules_without_architecture_entry.", + "_selector_parse": "Private include-select parser; see modules_without_architecture_entry.", + "architecture_sync_helper": "architecture_sync filename helper; see modules_without_architecture_entry.", + "checkup_target": "checkup target classifier; see modules_without_architecture_entry.", + "compression_reporting": "context-compression reporting; see modules_without_architecture_entry.", + "context_snapshot_policy": "snapshot policy checks; see modules_without_architecture_entry.", + "continuous_sync": "continuous-sync classification; see modules_without_architecture_entry.", + "drift_main": "`pdd checkup drift` CLI wiring; see modules_without_architecture_entry.", + "gate_main": "`pdd checkup gate` CLI wiring; hand-written `_main`, already registered in architecture.json without a generating prompt.", + "grounding_provenance": "grounding metadata helpers; see modules_without_architecture_entry.", + "interface_semantics": "interface-conformance helpers; see modules_without_architecture_entry.", + "json_atomic": "atomic JSON writer; see modules_without_architecture_entry.", + "json_invocation": "JSON-only invocation detector; see modules_without_architecture_entry.", + "language_extensions": "canonical extension table; see modules_without_architecture_entry.", + "list_drift_detection": "hardcoded-list drift detector; see modules_without_architecture_entry.", + "prompt_gate": "prompt-quality gate hooks; see modules_without_architecture_entry.", + "source_set_model": "checkup target->.prompt resolver; see modules_without_architecture_entry.", + "story_test_generation": "user-story pytest generator; see modules_without_architecture_entry.", + "sync_graph_order_consistency": "sync-order consistency detector; see modules_without_architecture_entry.", + "test_result": "shared test-command return type; see modules_without_architecture_entry.", + "waiver_policy": "waiver-status helpers; see modules_without_architecture_entry." + }, + "code_without_test": { + "__main__": "Thin `python -m pdd` shim; exercised via CLI end-to-end tests. TODO: add tests/test___main__.py or document coverage.", + "_keyring_timeout": "Bounded keyring wrappers; TODO add tests/test__keyring_timeout.py.", + "_selector_parse": "Include-select parser; TODO add tests/test__selector_parse.py.", + "architecture_sync_helper": "Filename-normalization helper; covered indirectly by test_architecture_sync. TODO add dedicated test.", + "checkup_file_selection": "checkup simplify file discovery; TODO add tests/test_checkup_file_selection.py.", + "checkup_interactive_main": "Interactive checkup orchestration; TODO add tests/test_checkup_interactive_main.py.", + "checkup_planner": "Checkup tool planners; TODO add tests/test_checkup_planner.py.", + "checkup_simplify": "checkup simplify core; TODO add tests/test_checkup_simplify.py.", + "checkup_simplify_claude": "Claude /simplify helpers; TODO add tests/test_checkup_simplify_claude.py.", + "checkup_tools": "Checkup engine wrappers; TODO add tests/test_checkup_tools.py.", + "cli_branding": "User-facing branding strings; low-risk constants. TODO add tests/test_cli_branding.py.", + "compression_reporting": "context-compression reporting; TODO add tests/test_compression_reporting.py.", + "config_resolution": "Centralized config resolution; TODO add tests/test_config_resolution.py.", + "continuous_sync": "continuous-sync classification; TODO add tests/test_continuous_sync.py.", + "contract_ir": "Contract authoring IR; TODO add tests/test_contract_ir.py.", + "edit_file": "LLM file editor; TODO add tests/test_edit_file.py.", + "evidence_store": "Evidence manifest loader; TODO add tests/test_evidence_store.py.", + "gate_policy": "checkup gate YAML policy loader; TODO add tests/test_gate_policy.py.", + "json_atomic": "atomic JSON writer; TODO add tests/test_json_atomic.py.", + "python_env_detector": "Host Python env detector; TODO add tests/test_python_env_detector.py.", + "test_result": "shared test-command return type; TODO add tests/test_test_result.py.", + "validate_prompt_includes": " validation/cleanup; TODO add tests/test_validate_prompt_includes.py." + } + } +} diff --git a/tests/test_architecture_completeness.py b/tests/test_architecture_completeness.py new file mode 100644 index 0000000000..70df27f5a9 --- /dev/null +++ b/tests/test_architecture_completeness.py @@ -0,0 +1,280 @@ +"""Bijection gate for architecture.json completeness. + +``architecture.json`` is the module registry that drives project-wide sync: a +no-arg ``pdd sync`` enumerates modules *from* this file +(``pdd.agentic_sync._architecture_sync_modules``), so any top-level ``pdd/*.py`` +module without an entry is invisible to global sync and dependency-ordered heal. + +This test asserts a **bijection**: every top-level ``pdd/*.py`` module (after +applying ``.pddignore``) has exactly one architecture entry, UNLESS it is listed +in ``architecture_waivers.json`` under ``modules_without_architecture_entry`` +(hand-written utilities/CLI wiring with no generating prompt). It also asserts +every entry's ``filepath`` and ``filename`` exist on disk, and ratchets the +adjacent orphan gaps (prompt-no-code, code-no-prompt, code-no-test) so new gaps +must be documented rather than appearing silently. + +To fix a failure: +- module missing an entry -> run ``pdd sync-architecture`` or author the entry, + or (for promptless hand-written modules) add it to the waiver with a reason. +- stale waiver -> delete the line once the module has an entry / is removed. +- new orphan -> add a one-line justification under the relevant ``orphans`` list. +""" +from __future__ import annotations + +import json +from pathlib import Path +from typing import Dict, List, Set + +import pytest + +from pdd.agentic_sync_runner import _basename_from_architecture_filename +from pdd.architecture_registry import extract_modules +from pdd.update_main import _is_pddignored, _load_pddignore + +REPO_ROOT = Path(__file__).resolve().parent.parent +ARCHITECTURE_JSON = REPO_ROOT / "architecture.json" +WAIVERS_JSON = REPO_ROOT / "architecture_waivers.json" + +# Fields present in every architecture entry today (the hard invariant). +REQUIRED_ENTRY_FIELDS = ( + "reason", + "dependencies", + "priority", + "filename", + "filepath", + "tags", + "interface", +) + + +# --------------------------------------------------------------------------- # +# Fixtures / shared computation # +# --------------------------------------------------------------------------- # +@pytest.fixture(scope="module") +def entries() -> List[dict]: + return extract_modules(json.loads(ARCHITECTURE_JSON.read_text(encoding="utf-8"))) + + +@pytest.fixture(scope="module") +def waivers() -> dict: + return json.loads(WAIVERS_JSON.read_text(encoding="utf-8")) + + +def _candidate_modules() -> Dict[str, Path]: + """Top-level ``pdd/*.py`` modules that survive ``.pddignore`` (the sync scope).""" + patterns, pddignore_root = _load_pddignore(str(REPO_ROOT)) + modules: Dict[str, Path] = {} + for path in sorted(REPO_ROOT.glob("pdd/*.py")): + if _is_pddignored(str(path), pddignore_root, patterns): + continue + modules[path.stem] = path + return modules + + +def _covered_toplevel_modules(entries: List[dict]) -> Set[str]: + """Module basenames covered by an entry whose ``filepath`` is ``pdd/.py``.""" + covered: Set[str] = set() + for entry in entries: + filepath = str(entry.get("filepath") or "").replace("\\", "/").strip().lstrip("/") + if not filepath: + continue + path = Path(filepath) + if path.parent == Path("pdd") and path.suffix == ".py": + covered.add(path.stem) + return covered + + +def _prompt_basenames() -> Dict[str, List[str]]: + """Top-level ``prompts/*.prompt`` grouped by module basename (LLM-only skipped).""" + grouped: Dict[str, List[str]] = {} + for prompt in sorted((REPO_ROOT / "prompts").glob("*.prompt")): + base = _basename_from_architecture_filename(prompt.name) + if base: + grouped.setdefault(base, []).append(prompt.name) + return grouped + + +def _resolve_prompt(filename: str) -> bool: + filename = (filename or "").replace("\\", "/").lstrip("/") + if not filename: + return False + candidates = [ + REPO_ROOT / "prompts" / filename, + REPO_ROOT / filename, + REPO_ROOT / "prompts" / Path(filename).name, + REPO_ROOT / "pdd" / "prompts" / filename, + REPO_ROOT / "pdd" / "prompts" / Path(filename).name, + ] + return any(candidate.exists() for candidate in candidates) + + +def _bijection_gap(entries: List[dict], waivers: dict): + """Return (undocumented_missing, stale_waivers) for the module<->entry bijection.""" + modules = set(_candidate_modules()) + covered = _covered_toplevel_modules(entries) & modules + missing = modules - covered + waived = set(waivers.get("modules_without_architecture_entry", {})) + undocumented_missing = sorted(missing - waived) + # stale = waived but the module now has an entry, or no longer exists on disk + stale = sorted((waived & covered) | {m for m in waived if m not in modules}) + return undocumented_missing, stale + + +# --------------------------------------------------------------------------- # +# Structural sanity # +# --------------------------------------------------------------------------- # +def test_architecture_json_is_nonempty_list(entries: List[dict]) -> None: + assert entries, "architecture.json parsed to zero module entries" + + +def test_entries_have_required_fields(entries: List[dict]) -> None: + offenders: List[str] = [] + for entry in entries: + missing = [f for f in REQUIRED_ENTRY_FIELDS if f not in entry] + if missing: + offenders.append(f"{entry.get('filename') or entry.get('filepath')!r}: missing {missing}") + assert not offenders, "architecture entries missing required fields:\n " + "\n ".join(offenders) + + +def test_entries_have_description(entries: List[dict], waivers: dict) -> None: + """Every entry should carry a description, minus documented pre-existing gaps.""" + allowed = set(waivers["known_registry_exceptions"]["entries_without_description"]) + offenders = sorted( + str(e.get("filename")) + for e in entries + if "description" not in e and str(e.get("filename")) not in allowed + ) + assert not offenders, ( + "architecture entries missing 'description' (add one, or document under " + "known_registry_exceptions.entries_without_description):\n " + "\n ".join(offenders) + ) + + +def test_no_duplicate_filepaths(entries: List[dict], waivers: dict) -> None: + """Bijection direction: at most one entry per code file (minus tracked pre-existing dupes).""" + allowed = set(waivers["known_registry_exceptions"]["duplicate_filepaths"]) + seen: Dict[str, int] = {} + for entry in entries: + fp = str(entry.get("filepath") or "").strip() + if fp: + seen[fp] = seen.get(fp, 0) + 1 + dupes = {fp: n for fp, n in seen.items() if n > 1 and fp not in allowed} + assert not dupes, ( + "duplicate filepaths in architecture.json (one entry per module expected; " + "document a known pre-existing dupe under known_registry_exceptions.duplicate_filepaths):\n " + + "\n ".join(f"{fp} x{n}" for fp, n in sorted(dupes.items())) + ) + + +def test_every_entry_points_at_real_files(entries: List[dict]) -> None: + """Every entry's filepath (code) and filename (prompt) must exist on disk.""" + bad_filepath: List[str] = [] + bad_filename: List[str] = [] + for entry in entries: + fp = str(entry.get("filepath") or "").replace("\\", "/").strip().lstrip("/") + if not fp or not (REPO_ROOT / fp).exists(): + bad_filepath.append(f"{entry.get('filename')!r} -> filepath {entry.get('filepath')!r}") + if not _resolve_prompt(entry.get("filename", "")): + bad_filename.append(f"{entry.get('filename')!r} (filepath {entry.get('filepath')!r})") + msg = [] + if bad_filepath: + msg.append("entries whose filepath is missing on disk:\n " + "\n ".join(bad_filepath)) + if bad_filename: + msg.append("entries whose filename prompt is missing on disk:\n " + "\n ".join(bad_filename)) + assert not msg, "\n".join(msg) + + +# --------------------------------------------------------------------------- # +# The bijection gate # +# --------------------------------------------------------------------------- # +def test_module_entry_bijection(entries: List[dict], waivers: dict) -> None: + undocumented_missing, stale = _bijection_gap(entries, waivers) + problems: List[str] = [] + if undocumented_missing: + problems.append( + "top-level pdd/*.py modules with no architecture.json entry and no waiver:\n " + + "\n ".join(undocumented_missing) + + "\n-> run `pdd sync-architecture` / author an entry, or add each to " + "architecture_waivers.json 'modules_without_architecture_entry' with a one-line reason." + ) + if stale: + problems.append( + "stale waivers in architecture_waivers.json 'modules_without_architecture_entry' " + "(module now has an entry or no longer exists):\n " + "\n ".join(stale) + + "\n-> delete these lines." + ) + assert not problems, "\n\n".join(problems) + + +def test_waived_modules_have_no_entry(entries: List[dict], waivers: dict) -> None: + """A waived module must genuinely lack an entry (keeps the waiver honest).""" + covered = _covered_toplevel_modules(entries) + both = sorted(set(waivers.get("modules_without_architecture_entry", {})) & covered) + assert not both, ( + "modules both waived AND present in architecture.json (remove the waiver):\n " + + "\n ".join(both) + ) + + +# --------------------------------------------------------------------------- # +# Orphan ratchet (new gaps must be documented; fixing a gap needs no edit) # +# --------------------------------------------------------------------------- # +def test_prompt_without_code_ratchet(waivers: dict) -> None: + prompt_bases = _prompt_basenames() + computed = {b for b in prompt_bases if not (REPO_ROOT / "pdd" / f"{b}.py").exists()} + documented = set(waivers["orphans"]["prompt_without_code"]) + undocumented = sorted(computed - documented) + assert not undocumented, ( + "prompt(s) with no corresponding pdd/.py not documented in " + "architecture_waivers.json orphans.prompt_without_code:\n " + "\n ".join(undocumented) + ) + + +def test_code_without_prompt_ratchet(waivers: dict) -> None: + modules = _candidate_modules() + prompt_bases = _prompt_basenames() + computed = {m for m in modules if m not in prompt_bases} + documented = set(waivers["orphans"]["code_without_prompt"]) + undocumented = sorted(computed - documented) + assert not undocumented, ( + "module(s) with no top-level prompt not documented in " + "architecture_waivers.json orphans.code_without_prompt:\n " + "\n ".join(undocumented) + ) + + +def test_code_without_test_ratchet(waivers: dict) -> None: + modules = _candidate_modules() + computed = {m for m in modules if not (REPO_ROOT / "tests" / f"test_{m}.py").exists()} + documented = set(waivers["orphans"]["code_without_test"]) + undocumented = sorted(computed - documented) + assert not undocumented, ( + "module(s) with no tests/test_.py not documented in " + "architecture_waivers.json orphans.code_without_test:\n " + "\n ".join(undocumented) + ) + + +# --------------------------------------------------------------------------- # +# Meta: prove the gate has teeth (acceptance criterion) # +# --------------------------------------------------------------------------- # +def test_gate_detects_removed_entry(entries: List[dict], waivers: dict) -> None: + """Deleting a covered module's entry must surface as an undocumented gap.""" + covered = sorted(_covered_toplevel_modules(entries) & set(_candidate_modules())) + assert covered, "expected at least one covered top-level module" + victim = "construct_paths" if "construct_paths" in covered else covered[0] + pruned = [e for e in entries if Path(str(e.get("filepath") or "")).stem != victim] + undocumented_missing, _ = _bijection_gap(pruned, waivers) + assert victim in undocumented_missing, ( + f"bijection gate failed to detect a removed entry for {victim!r}" + ) + + +def test_gate_detects_unwaived_new_module(entries: List[dict], waivers: dict) -> None: + """A module present neither as an entry nor a waiver must fail the gate.""" + phantom = "zzz_phantom_module_for_test" + waived = set(waivers.get("modules_without_architecture_entry", {})) + covered = _covered_toplevel_modules(entries) + # Simulate the gap computation with an extra on-disk module. + modules = set(_candidate_modules()) | {phantom} + missing = modules - (covered & modules) + undocumented = sorted(missing - waived) + assert phantom in undocumented, "bijection gate failed to detect an unwaived new module" From 493587a874cbff173d352ff07e61034ea7e8ddcd Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:48:35 -0700 Subject: [PATCH 07/30] ci(unit-tests): add architecture completeness gate step Run tests/test_architecture_completeness.py as an explicit named step in the Unit Tests job, alongside the existing validate-arch-includes checks. The full `pytest tests/` run already collects it; this dedicated step makes the module<->architecture.json bijection gate visible and fast-failing. Co-Authored-By: Claude --- .github/workflows/unit-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f79d1bd692..ab18ed5a4e 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -61,6 +61,9 @@ jobs: - name: Validate architecture vs prompt includes (repo, non-sample trees) run: pdd checkup --validate-arch-includes + - name: Architecture completeness gate (module <-> architecture.json bijection) + run: pytest tests/test_architecture_completeness.py -q --no-header + - name: Run unit tests run: > pytest tests/ From 0fcfa45f9839780d9c466cb9932e253cfbd456ad Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:48:36 -0700 Subject: [PATCH 08/30] Add stdlib .pdd/meta fingerprint stamper + waivers (part of #1927) scripts/stamp_fingerprints.py recomputes every dev unit's fingerprint from disk (composite prompt_hash + include_deps + code/example/test hashes) and writes it byte-identically to how `pdd sync` persists it. It is stdlib-only (no pdd import, no LLM): the hashing is vendored verbatim from sync_determine_operation.py, and code/example/test paths are resolved by the .pddrc convention plus architecture.json overrides (issue #225 filepath, issue #1677 ambiguous-leaf stem disambiguation), so recomputed hashes match the CLI for every unit. --check recomputes and diffs against the committed metas, exiting non-zero on drift or a missing/hand-edited fingerprint. This is the primitive the CI gate and audits reuse. scripts/fingerprint_waivers.json lists the units `pdd sync` itself cannot fingerprint (ambiguous bare leaves cli/gate; core_dump_smoke and server/routes/session have no code file), so --check excludes them. tests/test_stamp_fingerprints.py pins hash parity against pdd's own calculate_current_hashes for representative units (flat, subdir, architecture-overridden, ambiguous-leaf), the no-trailing-newline byte format, --check drift detection on a tampered meta, and waiver/coverage classification. Co-Authored-By: Claude --- scripts/fingerprint_waivers.json | 21 + scripts/stamp_fingerprints.py | 695 +++++++++++++++++++++++++++++++ tests/test_stamp_fingerprints.py | 156 +++++++ 3 files changed, 872 insertions(+) create mode 100644 scripts/fingerprint_waivers.json create mode 100644 scripts/stamp_fingerprints.py create mode 100644 tests/test_stamp_fingerprints.py diff --git a/scripts/fingerprint_waivers.json b/scripts/fingerprint_waivers.json new file mode 100644 index 0000000000..d0f8bb2dba --- /dev/null +++ b/scripts/fingerprint_waivers.json @@ -0,0 +1,21 @@ +{ + "_comment": "Units enumerated from pdd/prompts/*_python.prompt that intentionally have NO committed .pdd/meta fingerprint. scripts/stamp_fingerprints.py --check excludes these from both the coverage requirement and hash verification. Keep the list minimal and justified; a unit belongs here only when `pdd sync` itself cannot produce a fingerprint for it (ambiguous module identity, or no code file on disk).", + "waivers": [ + { + "basename": "cli", + "reason": "Ambiguous module identity: the bare leaf 'cli' maps to two files in architecture.json (pdd/cli.py and pdd/core/cli.py), so `pdd sync cli` raises AmbiguousModuleError and never writes a fingerprint. The path-qualified unit core/cli is stamped for pdd/core/cli.py; pdd/cli.py is a thin re-export shim reached only by path-qualified sync." + }, + { + "basename": "gate", + "reason": "Ambiguous module identity: the bare leaf 'gate' maps to two files in architecture.json (pdd/commands/gate.py and pdd/gate_main.py) and has no pdd/gate.py by .pddrc convention, so `pdd sync gate` raises AmbiguousModuleError. The path-qualified unit commands/gate is stamped for pdd/commands/gate.py; pdd/gate_main.py has no prompt of its own." + }, + { + "basename": "core_dump_smoke", + "reason": "No code file on disk: pdd/core_dump_smoke.py does not exist, so there is nothing to hash. The prompt is a smoke-test fixture with no generated module." + }, + { + "basename": "server/routes/session", + "reason": "No code file on disk: pdd/server/routes/session.py does not exist (session handling lives elsewhere), so there is nothing to hash." + } + ] +} diff --git a/scripts/stamp_fingerprints.py b/scripts/stamp_fingerprints.py new file mode 100644 index 0000000000..72e8218048 --- /dev/null +++ b/scripts/stamp_fingerprints.py @@ -0,0 +1,695 @@ +#!/usr/bin/env python3 +"""Stamp / verify ``.pdd/meta`` fingerprints for every PDD dev unit (stdlib only). + +The committed ``.pdd/meta/.json`` fingerprints are the oracle ``pdd sync`` +trusts to decide whether a unit changed. When they are missing or stale, sync +diffs current files against absent/old hashes, sees phantom "changed" verdicts, +and regenerates mature modules (issue #1938). This script keeps that oracle +current for the whole tree: + +* ``stamp`` (default): for every unit, recompute all hashes from the files on + disk and write the fingerprint JSON, byte-identically to how ``pdd`` writes + it (``pdd/sync_orchestration.py`` ``_atomic_write`` / ``operation_log.save_fingerprint`` + -> ``json.dump(..., indent=2)`` with no trailing newline, ``Fingerprint`` + dataclass key order). Existing units keep their ``command``; new units get a + neutral ``command`` (see ``NEW_UNIT_COMMAND``). + +* ``--check``: recompute every unit's hashes and compare to the committed + fingerprint. Exit non-zero listing units whose stored hashes are stale (drift + or a hand-edit) or that have no committed fingerprint and are not waived. This + is the primitive the CI gate reuses. + +Stdlib only, no ``pdd`` import, no LLM: the hashing is vendored verbatim from +``pdd/sync_determine_operation.py`` (pinned byte-for-byte by the cross-check in +``tests/test_stamp_fingerprints.py``). Path resolution mirrors the repo's +``.pddrc`` convention: a prompt at ``pdd/prompts//_python.prompt`` +maps to code ``pdd//.py``, example ``context//_example.py``, +tests ``tests//test_*.py``. + +Never hand-edit ``.pdd/meta``; regenerate via this stamper (see CONTRIBUTING.md). +""" +from __future__ import annotations + +import argparse +import fnmatch +import glob +import hashlib +import json +import os +import re +import subprocess +import sys +from datetime import datetime, timezone +from pathlib import Path +from typing import Dict, List, Optional, Tuple + +# --- Repo layout ------------------------------------------------------------- + +REPO_ROOT = Path(__file__).resolve().parent.parent +PROMPTS_ROOT = REPO_ROOT / "pdd" / "prompts" +META_DIR = REPO_ROOT / ".pdd" / "meta" +WAIVERS_FILE = REPO_ROOT / "scripts" / "fingerprint_waivers.json" +ARCHITECTURE_FILE = REPO_ROOT / "architecture.json" + +LANGUAGE = "python" +PROMPT_SUFFIX = "_python.prompt" + +# The ``command`` recorded for a freshly-created fingerprint. ``pdd sync``'s +# completion gate (sync_determine_operation.py: COMPLETED_VERIFY_COMMANDS / +# COMPLETED_TEST_COMMANDS = {'verify','test','fix','update'} / {'test','fix', +# 'update'}) treats a unit as "workflow complete" -> nothing to do only when the +# command is in {test, fix, update}. 'fix' is chosen because it satisfies both +# gates, triggers none of the special branches ('auto-deps' forces generate, +# 'crash' forces a retry, a 'skip:' prefix means skipped), and is already the +# modal command among committed fingerprints. The epoch stamp declares the +# current tree the agreed baseline, so a terminal at-rest command is truthful. +NEW_UNIT_COMMAND = "fix" + +# Fingerprint dataclass field order (pdd/sync_determine_operation.py Fingerprint). +# Written key order MUST match so a subsequent `pdd sync` produces no spurious diff. +FIELD_ORDER = ( + "pdd_version", + "timestamp", + "command", + "prompt_hash", + "code_hash", + "example_hash", + "test_hash", + "test_files", + "include_deps", +) + +# Hash fields --check recomputes and compares (metadata fields pdd_version / +# timestamp / command are not content-derived and are not checked). +HASH_FIELDS = ( + "prompt_hash", + "code_hash", + "example_hash", + "test_hash", + "test_files", + "include_deps", +) + + +# --- BEGIN verbatim copies from pdd/pdd/sync_determine_operation.py ----------- +# Keep byte-for-byte identical to pdd so recomputed hashes match the CLI. Pinned +# by tests/test_stamp_fingerprints.py::test_hash_parity_with_pdd. + +_INCLUDE_PATTERN = re.compile(r"]*>(.*?)") +_BACKTICK_INCLUDE_PATTERN = re.compile(r"```<([^>]*?)>```") + + +def calculate_sha256(file_path: Path) -> Optional[str]: + """Calculates the SHA256 hash of a file if it exists.""" + if not file_path.exists(): + return None + + try: + hasher = hashlib.sha256() + with open(file_path, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hasher.update(chunk) + return hasher.hexdigest() + except (IOError, OSError): + return None + + +def _resolve_include_path(include_ref: str, prompt_dir: Path) -> Optional[Path]: + """Resolve an reference to an absolute Path.""" + p = Path(include_ref) + if p.is_absolute() and p.exists(): + return p + candidate = prompt_dir / include_ref + if candidate.exists(): + return candidate + candidate = Path.cwd() / include_ref + if candidate.exists(): + return candidate + return None + + +def extract_include_deps(prompt_path: Path) -> Dict[str, str]: + """Extract include dependency paths and their hashes from a prompt file. + + Returns a dict mapping resolved dependency paths to their SHA256 hashes. + Only includes dependencies that exist on disk. + """ + if not prompt_path.exists(): + return {} + + try: + prompt_content = prompt_path.read_text(encoding="utf-8", errors="ignore") + except (IOError, OSError): + return {} + + include_refs = _INCLUDE_PATTERN.findall(prompt_content) + include_refs += _BACKTICK_INCLUDE_PATTERN.findall(prompt_content) + + if not include_refs: + return {} + + deps = {} + prompt_dir = prompt_path.parent + for ref in sorted(set(r.strip() for r in include_refs)): + dep_path = _resolve_include_path(ref, prompt_dir) + if dep_path and dep_path.exists(): + dep_hash = calculate_sha256(dep_path) + if dep_hash: + try: + rel_path = dep_path.relative_to(Path.cwd()) + except ValueError: + rel_path = dep_path + deps[str(rel_path)] = dep_hash + + return deps + + +def calculate_prompt_hash( + prompt_path: Path, stored_deps: Optional[Dict[str, str]] = None +) -> Optional[str]: + """Hash a prompt file including the content of all its dependencies. + + If the prompt has tags, extracts and hashes those dependencies. + If no tags are found but stored_deps is provided (from a previous fingerprint), + uses those stored dependency paths to compute the hash. This handles the case + where the auto-deps step strips tags from the prompt file. + """ + if not prompt_path.exists(): + return None + + try: + prompt_content = prompt_path.read_text(encoding="utf-8", errors="ignore") + except (IOError, OSError): + return None + + # Try to find include refs in current prompt content + include_refs = _INCLUDE_PATTERN.findall(prompt_content) + include_refs += _BACKTICK_INCLUDE_PATTERN.findall(prompt_content) + + # Resolve to actual paths + prompt_dir = prompt_path.parent + dep_paths = [] + if include_refs: + for ref in sorted(set(r.strip() for r in include_refs)): + dep_path = _resolve_include_path(ref, prompt_dir) + if dep_path and dep_path.exists(): + dep_paths.append(dep_path) + elif stored_deps: + # No include tags in prompt - use stored dependency paths from fingerprint + for dep_path_str in sorted(stored_deps.keys()): + dep_path = Path(dep_path_str) + if dep_path.exists(): + dep_paths.append(dep_path) + + if not dep_paths: + return calculate_sha256(prompt_path) + + # Build composite hash: prompt bytes + sorted dependency contents + hasher = hashlib.sha256() + try: + with open(prompt_path, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hasher.update(chunk) + except (IOError, OSError): + return None + + for dep_path in dep_paths: + try: + with open(dep_path, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hasher.update(chunk) + except (IOError, OSError): + pass + + return hasher.hexdigest() + + +# --- END verbatim copies ----------------------------------------------------- + + +def refresh_include_deps( + prompt_path: Path, stored_deps: Optional[Dict[str, str]] = None +) -> Dict[str, str]: + """Recompute ``include_deps`` mirroring pdd's ``calculate_current_hashes``. + + Ports the prompt branch of ``sync_determine_operation.calculate_current_hashes``: + extract fresh deps from the prompt's tags; if the prompt no longer + has tags but stored deps exist (auto-deps stripped, issue #522), re-hash the + stored dependency keys. + """ + deps = extract_include_deps(prompt_path) + if not deps and stored_deps: + updated_deps: Dict[str, str] = {} + for dep_path_str, _old_hash in stored_deps.items(): + dep_path = Path(dep_path_str) + if dep_path.exists(): + new_hash = calculate_sha256(dep_path) + if new_hash: + updated_deps[dep_path_str] = new_hash + deps = updated_deps + return deps + + +def _safe_basename(basename: str) -> str: + """Sanitize basename for use in metadata filenames ('/' -> '_').""" + return basename.replace("/", "_") + + +# --- architecture.json resolution -------------------------------------------- +# pdd's get_pdd_file_paths consults architecture.json FIRST for a module's code +# filepath (issue #225), and disambiguates example/test stems for a bare leaf +# that maps to more than one module (issue #1677). Both are pure JSON+path logic +# (no LLM), so they are mirrored here. For the ~99% of units whose architecture +# filepath equals the .pddrc convention pdd/.py, this changes nothing; +# it corrects the handful whose code lives outside the prompt's subdir (e.g. +# commands/checkup_simplify -> pdd/checkup_simplify.py) and the ambiguous leaves +# cli/gate. + + +def _load_architecture(): + """Return ``(by_filename, by_leaf, ambiguous_leaves)`` from architecture.json. + + * ``by_filename``: full architecture filename (lower) -> set of filepaths. + Architecture filenames are frequently path-qualified (``core/cli_python.prompt``). + * ``by_leaf``: filename leaf (lower) -> set of filepaths. + * ``ambiguous_leaves``: basenames whose bare leaf maps to >1 distinct filepath + (mirrors ``_architecture_module_choices``; these get a disambiguated stem). + """ + by_filename: Dict[str, set] = {} + by_leaf: Dict[str, set] = {} + if not ARCHITECTURE_FILE.is_file(): + return by_filename, by_leaf, frozenset() + try: + data = json.loads(ARCHITECTURE_FILE.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + return by_filename, by_leaf, frozenset() + modules = data if isinstance(data, list) else data.get("modules", []) if isinstance(data, dict) else [] + for module in modules: + if not isinstance(module, dict): + continue + filename = str(module.get("filename") or "").strip() + filepath = str(module.get("filepath") or "").strip() + if not filename or not filepath or filename.endswith("_LLM.prompt"): + continue + fp = Path(filepath).as_posix() + by_filename.setdefault(filename.lower(), set()).add(fp) + by_leaf.setdefault(Path(filename).name.lower(), set()).add(fp) + ambiguous = frozenset( + leaf[: -len(f"_{LANGUAGE}.prompt")] + for leaf, fps in by_leaf.items() + if leaf.endswith(f"_{LANGUAGE}.prompt") and len(fps) > 1 + ) + return by_filename, by_leaf, ambiguous + + +_ARCH_BY_FILENAME, _ARCH_BY_LEAF, _AMBIGUOUS_LEAVES = _load_architecture() + + +def _resolve_code_and_stem(basename: str) -> Tuple[Path, str]: + """Return ``(code_path, artifact_stem)`` mirroring pdd's resolution. + + ``code_path`` is the architecture.json filepath when the prompt is listed + there, else the ``pdd/.py`` convention. ``artifact_stem`` is the + stem used for the example/test filenames: the code file's stem, replaced by + a ``_safe_basename()`` disambiguation when the bare leaf + is ambiguous (issue #1677). + """ + leaf = basename.rsplit("/", 1)[-1] + pf_full = f"{basename}_{LANGUAGE}.prompt".lower() + pf_leaf = f"{leaf}_{LANGUAGE}.prompt".lower() + + arch_fp: Optional[str] = None + full_fps = _ARCH_BY_FILENAME.get(pf_full) + if full_fps and len(full_fps) == 1: + arch_fp = next(iter(full_fps)) + if arch_fp is None: + leaf_fps = _ARCH_BY_LEAF.get(pf_leaf, set()) + if len(leaf_fps) == 1: + arch_fp = next(iter(leaf_fps)) + elif len(leaf_fps) > 1: + # Ambiguous bare leaf: accept only if exactly one filepath aligns + # with the path-qualified basename (flat ambiguous units are waived). + aligned = [ + fp for fp in leaf_fps + if Path(fp).with_suffix("").as_posix().endswith(basename) + ] + if len(aligned) == 1: + arch_fp = aligned[0] + + if arch_fp: + code = REPO_ROOT / arch_fp + if leaf in _AMBIGUOUS_LEAVES: + stem = _safe_basename(Path(arch_fp).with_suffix("").as_posix()) + else: + stem = Path(arch_fp).stem + else: + code = REPO_ROOT / "pdd" / f"{basename}.py" + stem = leaf + return code, stem + + +# --- Unit enumeration & path resolution -------------------------------------- + + +class Unit: + """A single PDD dev unit resolved from a ``*_python.prompt`` file.""" + + __slots__ = ("basename", "prompt", "code", "example", "test", "test_files", "meta") + + def __init__(self, basename: str, prompt: Path) -> None: + self.basename = basename + self.prompt = prompt + # Code path + artifact stem come from architecture.json (falling back to + # the pdd/.py convention); the example/test DIRECTORY follows + # the prompt's subdir (context/, tests/), mirroring pdd. + subdir = str(Path(basename).parent) if "/" in basename else "" + self.code, stem = _resolve_code_and_stem(basename) + example_dir = REPO_ROOT / "context" / subdir if subdir else REPO_ROOT / "context" + self.example = example_dir / f"{stem}_example.py" + test_dir = REPO_ROOT / "tests" / subdir if subdir else REPO_ROOT / "tests" + self.test = test_dir / f"test_{stem}.py" + self.test_files = _discover_test_files(test_dir, stem) + self.meta = META_DIR / f"{_safe_basename(basename)}_{LANGUAGE}.json" + + +def _discover_test_files(test_dir: Path, stem: str) -> List[Path]: + """Mirror pdd's Bug #156 test-file globbing: sorted ``test_*.py``. + + Matches ``get_pdd_file_paths``: glob ``test_*.py`` in the test dir, + falling back to the single primary test path when the dir or matches are + absent. + """ + primary = test_dir / f"test_{stem}.py" + if test_dir.is_dir(): + pattern = glob.escape(f"test_{stem}") + matches = sorted(test_dir.glob(f"{pattern}*.py")) + else: + matches = [primary] if primary.exists() else [] + return matches or [primary] + + +def infer_basename(prompt_path: Path) -> Optional[str]: + """Return the unit basename for a ``*_python.prompt`` file, or None. + + Basename is the path relative to ``pdd/prompts`` with the ``_python.prompt`` + suffix dropped, subdirectories preserved (e.g. ``commands/which``). + """ + name = prompt_path.name + if not name.endswith(PROMPT_SUFFIX): + return None + rel = prompt_path.relative_to(PROMPTS_ROOT) + stem = rel.name[: -len(PROMPT_SUFFIX)] + subdir = rel.parent + if str(subdir) == ".": + return stem + return (subdir / stem).as_posix() + + +def enumerate_units() -> List[Unit]: + """Return every python unit under ``pdd/prompts`` sorted by basename.""" + units: List[Unit] = [] + for prompt in sorted(PROMPTS_ROOT.rglob(f"*{PROMPT_SUFFIX}")): + basename = infer_basename(prompt) + if basename is None: + continue + units.append(Unit(basename, prompt)) + return units + + +# --- .pddignore -------------------------------------------------------------- + + +def load_pddignore() -> List[str]: + """Load ``.pddignore`` patterns from the repo root (comments/blank stripped).""" + path = REPO_ROOT / ".pddignore" + patterns: List[str] = [] + if not path.is_file(): + return patterns + for line in path.read_text(encoding="utf-8").splitlines(): + line = line.strip() + if not line or line.startswith("#"): + continue + patterns.append(line) + return patterns + + +def is_pddignored(code_path: Path, patterns: List[str]) -> bool: + """Mirror pdd/update_main.py ``_is_pddignored`` against the code path. + + Matches the repo-relative POSIX path and the basename via fnmatch, plus + directory-prefix patterns ending in '/'. + """ + try: + rel_path = code_path.resolve().relative_to(REPO_ROOT).as_posix() + except ValueError: + return False + basename = code_path.name + for pat in patterns: + if pat.endswith("/"): + dir_name = pat.rstrip("/") + parts = rel_path.split("/") + if dir_name in parts[:-1]: + return True + else: + if fnmatch.fnmatch(rel_path, pat): + return True + if fnmatch.fnmatch(basename, pat): + return True + return False + + +# --- Waivers ----------------------------------------------------------------- + + +def load_waivers() -> Dict[str, str]: + """Return ``{basename: reason}`` from the committed waiver file.""" + if not WAIVERS_FILE.is_file(): + return {} + data = json.loads(WAIVERS_FILE.read_text(encoding="utf-8")) + waivers: Dict[str, str] = {} + for entry in data.get("waivers", []): + waivers[entry["basename"]] = entry.get("reason", "") + return waivers + + +# --- Meta read / write ------------------------------------------------------- + + +def read_meta(meta_path: Path) -> Optional[Dict]: + """Read an existing fingerprint JSON, or None if absent/unreadable.""" + if not meta_path.exists(): + return None + try: + data = json.loads(meta_path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + return None + return data if isinstance(data, dict) else None + + +def compute_hashes(unit: Unit, stored_deps: Optional[Dict[str, str]]) -> Dict: + """Recompute all fingerprint hash fields for a unit from disk. + + Mirrors ``calculate_current_hashes``: composite ``prompt_hash`` (with stored + deps fallback), per-file sha256, and the Bug #156 ``test_files`` map. + """ + test_files = { + f.name: calculate_sha256(f) for f in unit.test_files if f.exists() + } + return { + "prompt_hash": calculate_prompt_hash(unit.prompt, stored_deps=stored_deps), + "code_hash": calculate_sha256(unit.code), + "example_hash": calculate_sha256(unit.example), + "test_hash": calculate_sha256(unit.test), + "test_files": test_files, + "include_deps": refresh_include_deps(unit.prompt, stored_deps), + } + + +def build_fingerprint(unit: Unit, pdd_version: str) -> Dict: + """Build the full fingerprint dict for a unit (preserving prior command).""" + existing = read_meta(unit.meta) + stored_deps = None + command = NEW_UNIT_COMMAND + if existing is not None: + sd = existing.get("include_deps") + stored_deps = sd if isinstance(sd, dict) else None + if existing.get("command"): + command = existing["command"] + hashes = compute_hashes(unit, stored_deps) + fingerprint = { + "pdd_version": pdd_version, + "timestamp": datetime.now(timezone.utc).isoformat(), + "command": command, + "prompt_hash": hashes["prompt_hash"], + "code_hash": hashes["code_hash"], + "example_hash": hashes["example_hash"], + "test_hash": hashes["test_hash"], + "test_files": hashes["test_files"], + "include_deps": hashes["include_deps"], + } + return {k: fingerprint[k] for k in FIELD_ORDER} + + +def write_meta(meta_path: Path, content: Dict) -> None: + """Write meta JSON byte-identically to pdd (indent=2, no trailing newline).""" + meta_path.parent.mkdir(parents=True, exist_ok=True) + with open(meta_path, "w", encoding="utf-8") as handle: + json.dump(content, handle, indent=2) + + +def current_pdd_version() -> str: + """Return the current tree's pdd version (``git describe`` tag, no leading v). + + setuptools_scm generates ``pdd/_version.py`` only at build time, so derive + from git tags for a source checkout. Falls back to '0.0.0' when git tags are + unavailable (the version field is metadata; --check does not compare it). + """ + try: + out = subprocess.run( + ["git", "-C", str(REPO_ROOT), "describe", "--tags", "--abbrev=0"], + capture_output=True, + text=True, + check=False, + ) + tag = (out.stdout or "").strip() + if tag: + return tag[1:] if tag.startswith("v") else tag + except (OSError, subprocess.SubprocessError): + pass + return "0.0.0" + + +# --- Unit classification ----------------------------------------------------- + + +def classify(units: List[Unit], pddignore: List[str], waivers: Dict[str, str]): + """Split units into (stampable, ignored, waived, no_code) buckets. + + * ignored: code path matches ``.pddignore`` (pdd never tracks these). + * waived: basename appears in the committed waiver file. + * no_code: code file absent and not already waived (cannot be hashed). + * stampable: everything else. + """ + stampable: List[Unit] = [] + ignored: List[Unit] = [] + waived: List[Unit] = [] + no_code: List[Unit] = [] + for unit in units: + if is_pddignored(unit.code, pddignore): + ignored.append(unit) + elif unit.basename in waivers: + waived.append(unit) + elif not unit.code.exists(): + no_code.append(unit) + else: + stampable.append(unit) + return stampable, ignored, waived, no_code + + +# --- Commands ---------------------------------------------------------------- + + +def cmd_stamp(args: argparse.Namespace) -> int: + """Recompute and write fingerprints for every stampable unit.""" + units = enumerate_units() + pddignore = load_pddignore() + waivers = load_waivers() + stampable, ignored, waived, no_code = classify(units, pddignore, waivers) + pdd_version = current_pdd_version() + + prev_cwd = Path.cwd() + os.chdir(REPO_ROOT) # include resolution + dep keys are cwd-relative + written = 0 + try: + for unit in stampable: + fingerprint = build_fingerprint(unit, pdd_version) + write_meta(unit.meta, fingerprint) + written += 1 + finally: + os.chdir(prev_cwd) + + print( + f"stamped {written} units (pdd_version={pdd_version}); " + f"ignored={len(ignored)} waived={len(waived)} no_code={len(no_code)}" + ) + if no_code: + print("WARNING: units with no code file (add to waivers):", file=sys.stderr) + for unit in no_code: + print(f" {unit.basename} -> {unit.code.relative_to(REPO_ROOT)}", file=sys.stderr) + return 1 + return 0 + + +def cmd_check(args: argparse.Namespace) -> int: + """Recompute hashes and diff against committed metas. Non-zero on drift.""" + units = enumerate_units() + pddignore = load_pddignore() + waivers = load_waivers() + stampable, ignored, waived, no_code = classify(units, pddignore, waivers) + + missing: List[str] = [] + stale: List[Tuple[str, List[str]]] = [] + unwaived_no_code: List[str] = [] + + prev_cwd = Path.cwd() + os.chdir(REPO_ROOT) + try: + for unit in no_code: + unwaived_no_code.append(unit.basename) + for unit in stampable: + existing = read_meta(unit.meta) + if existing is None: + missing.append(unit.basename) + continue + sd = existing.get("include_deps") + stored_deps = sd if isinstance(sd, dict) else None + current = compute_hashes(unit, stored_deps) + diffs = [ + field + for field in HASH_FIELDS + if (existing.get(field) or None) != (current.get(field) or None) + ] + if diffs: + stale.append((unit.basename, diffs)) + finally: + os.chdir(prev_cwd) + + ok = not (missing or stale or unwaived_no_code) + total = len(stampable) + print( + f"checked {total} stampable units; " + f"ignored={len(ignored)} waived={len(waived)}" + ) + if unwaived_no_code: + print(f"\n{len(unwaived_no_code)} unit(s) have no code file and no waiver:", file=sys.stderr) + for name in sorted(unwaived_no_code): + print(f" {name}", file=sys.stderr) + if missing: + print(f"\n{len(missing)} unit(s) missing a committed fingerprint:", file=sys.stderr) + for name in sorted(missing): + print(f" {name}", file=sys.stderr) + if stale: + print(f"\n{len(stale)} unit(s) have stale fingerprints (run: python scripts/stamp_fingerprints.py):", file=sys.stderr) + for name, diffs in sorted(stale): + print(f" {name}: {', '.join(diffs)}", file=sys.stderr) + if ok: + print("all fingerprints current") + return 0 + return 1 + + +def main(argv: Optional[List[str]] = None) -> int: + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument( + "--check", + action="store_true", + help="Verify committed fingerprints are current; exit non-zero on drift.", + ) + args = parser.parse_args(argv) + if args.check: + return cmd_check(args) + return cmd_stamp(args) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/test_stamp_fingerprints.py b/tests/test_stamp_fingerprints.py new file mode 100644 index 0000000000..27b733b531 --- /dev/null +++ b/tests/test_stamp_fingerprints.py @@ -0,0 +1,156 @@ +"""Tests for scripts/stamp_fingerprints.py — the .pdd/meta fingerprint stamper. + +The load-bearing guarantee is hash parity with the pdd CLI: a fingerprint the +stamper writes must equal what ``pdd sync`` would compute, or sync sees phantom +drift. ``test_hash_parity_with_pdd`` pins the vendored hashing against pdd's own +functions for representative units (flat, subdir, architecture-overridden, and +ambiguous-leaf). Exhaustive parity across all units is enforced by the stamper's +own ``--check`` on the committed tree (``test_check_passes_on_committed_tree``). +""" +import importlib.util +import json +import logging +import os +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parent.parent +STAMPER_PATH = REPO_ROOT / "scripts" / "stamp_fingerprints.py" + + +def _load_stamper(): + spec = importlib.util.spec_from_file_location("stamp_fingerprints", STAMPER_PATH) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +stamp = _load_stamper() + + +# Representative units: flat, each subdir context, the two architecture.json +# code-path overrides (checkup_simplify -> pdd/checkup_simplify.py, +# remote_session -> pdd/remote_session.py), and the two ambiguous leaves +# (core/cli, commands/gate) whose example/test stems are disambiguated. +_SAMPLE_UNITS = [ + "sync_orchestration", + "code_generator", + "commands/which", + "server/executor", + "server/routes/auth", + "core/cloud", + "commands/checkup_simplify", + "core/remote_session", + "core/cli", + "commands/gate", +] + + +def test_stamper_is_stdlib_only(): + """The stamper must not import pdd (it runs offline in CI / the nightly runner).""" + import ast + + tree = ast.parse(STAMPER_PATH.read_text(encoding="utf-8")) + imported = set() + for node in ast.walk(tree): + if isinstance(node, ast.Import): + imported.update(alias.name.split(".")[0] for alias in node.names) + elif isinstance(node, ast.ImportFrom) and node.module: + imported.add(node.module.split(".")[0]) + assert "pdd" not in imported + + +def test_write_meta_byte_format(tmp_path): + """Meta JSON is indent=2, no trailing newline, Fingerprint dataclass key order.""" + content = {k: None for k in stamp.FIELD_ORDER} + content["command"] = "fix" + content["test_files"] = {} + content["include_deps"] = {} + out = tmp_path / "x.json" + stamp.write_meta(out, content) + raw = out.read_text(encoding="utf-8") + assert not raw.endswith("\n") # matches pdd's json.dump(indent=2) writers + assert list(json.loads(raw).keys()) == list(stamp.FIELD_ORDER) + assert '\n "timestamp"' in raw # indent=2 + + +@pytest.mark.parametrize("basename", _SAMPLE_UNITS) +def test_hash_parity_with_pdd(basename): + """Stamper hashes must equal pdd's calculate_current_hashes for each unit.""" + logging.disable(logging.CRITICAL) + from pdd.sync_determine_operation import ( + get_pdd_file_paths, + calculate_current_hashes, + ) + + prev = Path.cwd() + os.chdir(REPO_ROOT) # cwd-relative include resolution for both sides + try: + unit = stamp.Unit(basename, REPO_ROOT / "pdd" / "prompts" / f"{basename}_python.prompt") + existing = stamp.read_meta(unit.meta) + stored_deps = None + if existing is not None and isinstance(existing.get("include_deps"), dict): + stored_deps = existing["include_deps"] + mine = stamp.compute_hashes(unit, stored_deps) + paths = get_pdd_file_paths(basename, "python") + theirs = calculate_current_hashes(paths, stored_include_deps=stored_deps) + finally: + os.chdir(prev) + + for field in stamp.HASH_FIELDS: + assert (mine.get(field) or None) == (theirs.get(field) or None), ( + f"{basename}.{field} diverged from pdd" + ) + + +def test_check_passes_on_committed_tree(): + """--check exits 0 on the current tree (acceptance: fresh clone check is green).""" + assert stamp.main(["--check"]) == 0 + + +def test_check_detects_tampered_meta(): + """A hand-edited (tampered) fingerprint must fail --check (acceptance #5).""" + units = stamp.enumerate_units() + stampable, _ig, _wv, _nc = stamp.classify( + units, stamp.load_pddignore(), stamp.load_waivers() + ) + target = next(u for u in stampable if u.meta.exists()) + original = target.meta.read_bytes() + try: + data = json.loads(original) + data["code_hash"] = "0" * 64 # simulate a hand-edit + target.meta.write_text(json.dumps(data, indent=2), encoding="utf-8") + assert stamp.main(["--check"]) == 1 + finally: + target.meta.write_bytes(original) + # tree restored -> check green again + assert stamp.main(["--check"]) == 0 + + +def test_waived_and_ignored_units_excluded(): + """Waived (ambiguous / no-code) and .pddignored units are not required to stamp.""" + units = stamp.enumerate_units() + stampable, ignored, waived, no_code = stamp.classify( + units, stamp.load_pddignore(), stamp.load_waivers() + ) + waived_names = {u.basename for u in waived} + assert {"cli", "gate", "core_dump_smoke", "server/routes/session"} <= waived_names + assert not no_code # every no-code unit is explicitly waived + ignored_names = {u.basename for u in ignored} + # __init__ prompts and architecture_registry are .pddignored + assert "architecture_registry" in ignored_names + assert any(n.endswith("__init__") for n in ignored_names) + # stampable and waived/ignored are disjoint + stampable_names = {u.basename for u in stampable} + assert stampable_names.isdisjoint(waived_names) + + +def test_every_stampable_unit_has_committed_meta(): + """Coverage: every stampable unit has a meta on disk (acceptance #2).""" + units = stamp.enumerate_units() + stampable, _ig, _wv, _nc = stamp.classify( + units, stamp.load_pddignore(), stamp.load_waivers() + ) + missing = [u.basename for u in stampable if not u.meta.exists()] + assert not missing, f"units missing committed meta: {missing}" From 45aaa1ce796d10b3eb920f0b3aeb509986d8c8dd Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:48:44 -0700 Subject: [PATCH 09/30] Track all dev-unit fingerprints; drop the .pdd/meta allowlist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The committed .pdd/meta/*.json set is the oracle `pdd sync` trusts for every decision, but it was a hand-maintained `!`-allowlist pinning only ~42 of 223 units — the stalest artifact in the repo. Remove the blanket `.pdd/meta/*.json` ignore and its per-file allowlist so every dev unit's fingerprint is tracked. Only transient files stay ignored: atomic-write temp files (`.pdd/meta/*.tmp`) and sync logs (via the global `*.log` rule). Run-report tracking (`*_run.json`) is left exactly as-is (out of scope). Document the policy in CONTRIBUTING.md: never hand-edit `.pdd/meta`; regenerate the whole set with scripts/stamp_fingerprints.py, which CI verifies via --check. Co-Authored-By: Claude --- .gitignore | 35 +++++++---------------------------- CONTRIBUTING.md | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 003e63fe71..7cffca5287 100644 --- a/.gitignore +++ b/.gitignore @@ -243,34 +243,13 @@ yarn.lock .pdd/* !.pdd/ !.pdd/meta/ -.pdd/meta/*.json -!.pdd/meta/agentic_bug_orchestrator_python.json -!.pdd/meta/agentic_bug_python.json -!.pdd/meta/agentic_checkup_python.json -!.pdd/meta/agentic_checkup_orchestrator_python.json -# Agentic helper fingerprints are regenerated by auto-heal and intentionally -# remain ignored unless a module has an explicit reason to pin metadata. -!.pdd/meta/agentic_e2e_fix_orchestrator_python.json -!.pdd/meta/checkup_review_loop_python.json -!.pdd/meta/commands_checkup_python.json -!.pdd/meta/commands_prompt_python.json -!.pdd/meta/construct_paths_python.json -!.pdd/meta/prompt_lint_python.json -!.pdd/meta/core_cloud_python.json -!.pdd/meta/fix_code_loop_python.json -!.pdd/meta/fix_error_loop_python.json -!.pdd/meta/get_comment_python.json -!.pdd/meta/get_test_command_python.json -!.pdd/meta/git_update_python.json -!.pdd/meta/llm_invoke_python.json -!.pdd/meta/preprocess_python.json -!.pdd/meta/summarize_directory_python.json -!.pdd/meta/sync_determine_operation_python.json -!.pdd/meta/sync_tui_python.json -# Design-refresh (PR #1561) dev units: track their fingerprints so the auto-heal -# drift detector sees committed metadata for the modules this PR changed. -!.pdd/meta/cli_theme_python.json -!.pdd/meta/sync_animation_python.json +# Track ALL dev-unit fingerprints (global-sync issue A). The committed +# .pdd/meta/*.json set is the oracle `pdd sync` trusts for every decision, so it +# must be complete and current, not a hand-maintained allowlist. Regenerate the +# whole set with scripts/stamp_fingerprints.py (never hand-edit; see +# CONTRIBUTING.md). Only transient files stay ignored: atomic-write temp files +# below, and sync logs via the global `*.log` rule above. +.pdd/meta/*.tmp .pdd/meta/*_run.json # Issue #1006 follow-up: these two modules' tests pass quickly but # `pdd sync` runs >20 minutes on them in CI, hitting the auto-heal diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5eeaf8716b..0cb10b9387 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,6 +21,23 @@ Each complete change ideally includes four elements: - Example interface: usage examples that enable prompt composability. - Tests: appended to relevant test files to reproduce bugs or validate features. +## Fingerprints (`.pdd/meta`) +Every dev unit has a committed fingerprint in `.pdd/meta/_.json` recording the +SHA-256 of its prompt (plus `` deps), code, example, and tests. This committed set is +the oracle `pdd sync` trusts to decide whether a unit changed — a stale or missing fingerprint +makes sync see phantom drift and regenerate a mature module. So: + +- **Never hand-edit `.pdd/meta`.** Regenerate the whole set with the stamper: + ```bash + python scripts/stamp_fingerprints.py # restamp every unit + python scripts/stamp_fingerprints.py --check # verify (what CI runs; exits non-zero on drift) + ``` +- **All** dev units are tracked (no `.gitignore` allowlist). If you add or change a prompt/code + file, run the stamper and commit the updated `.pdd/meta/*.json`. CI's `--check` gate fails + otherwise. +- A unit that `pdd sync` genuinely cannot fingerprint (ambiguous module identity, or no code file + on disk) is listed with a justification in `scripts/fingerprint_waivers.json`. + ## Contribution Workflow 1) Get set up - Fork the repository and clone your fork. From 46a56a4c1bd2ca9344a293649d9739b79563a2a3 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:49:04 -0700 Subject: [PATCH 10/30] Sync epoch: stamp current fingerprints for all 223 dev units One-time epoch stamp (scripts/stamp_fingerprints.py). Declares the current tree the agreed sync baseline: recompute every unit's prompt/code/example/test hashes so the committed .pdd/meta is a trustworthy three-way merge-base. Refreshes 42 stale fingerprints (some pinned at 0.0.234 from May) and adds 181 that were never committed. Pre-existing prompt/code divergence is accepted here by design (back-propagation is a follow-up); what matters is that FUTURE drift is detected against a true base. Verified: a mature module that previously resolved to `fail_and_request_manual_merge` against its stale fingerprint now reports a benign decision, and no module resolves to a phantom generate/auto-deps/update. Co-Authored-By: Claude --- .pdd/meta/_keyring_timeout_python.json | 13 ++++++++ ...ntic_architecture_orchestrator_python.json | 17 ++++++---- .pdd/meta/agentic_architecture_python.json | 14 ++++++++ .../meta/agentic_bug_orchestrator_python.json | 18 +++++----- .pdd/meta/agentic_bug_python.json | 17 +++++----- .../agentic_change_orchestrator_python.json | 25 +++++++------- .pdd/meta/agentic_change_python.json | 18 ++++++++++ .../agentic_checkup_orchestrator_python.json | 18 +++++----- .pdd/meta/agentic_checkup_python.json | 15 +++++---- .pdd/meta/agentic_common_python.json | 22 +++++++++++++ .pdd/meta/agentic_common_worktree_python.json | 16 +++++++++ .pdd/meta/agentic_crash_python.json | 19 +++++++++++ .../agentic_e2e_fix_orchestrator_python.json | 18 +++++----- .pdd/meta/agentic_e2e_fix_python.json | 19 +++++++++++ .pdd/meta/agentic_fix_python.json | 20 +++++++++++ .pdd/meta/agentic_langtest_python.json | 15 +++++++++ .pdd/meta/agentic_multishot_python.json | 8 ++--- .../agentic_split_orchestrator_python.json | 16 ++++++--- .pdd/meta/agentic_split_python.json | 22 +++++++++++++ .pdd/meta/agentic_sync_python.json | 25 ++++++++++++++ .pdd/meta/agentic_sync_runner_python.json | 16 ++++----- .pdd/meta/agentic_test_generate_python.json | 17 ++++++++++ .../agentic_test_orchestrator_python.json | 18 ++++++++++ .pdd/meta/agentic_test_python.json | 20 +++++++++++ .pdd/meta/agentic_update_python.json | 20 +++++++++++ .pdd/meta/agentic_verify_python.json | 18 ++++++++++ .pdd/meta/api_contract_slicer_python.json | 15 +++++++++ .pdd/meta/api_key_scanner_python.json | 13 ++++++++ ...rchitecture_include_validation_python.json | 16 +++++++++ .pdd/meta/architecture_sync_python.json | 6 ++-- .pdd/meta/auth_service_python.json | 17 ++++++++++ .pdd/meta/auto_deps_architecture_python.json | 17 ++++++++++ .pdd/meta/auto_deps_main_python.json | 23 +++++++++++++ .pdd/meta/auto_include_python.json | 19 +++++++++++ .pdd/meta/auto_update_python.json | 13 ++++++++ .pdd/meta/bug_main_python.json | 21 ++++++++++++ .pdd/meta/bug_to_unit_test_python.json | 20 +++++++++++ .pdd/meta/change_main_python.json | 21 ++++++++++++ .pdd/meta/change_python.json | 22 +++++++++++++ .pdd/meta/checkup_agent_python.json | 13 ++++++++ .pdd/meta/checkup_file_selection_python.json | 13 ++++++++ .pdd/meta/checkup_gates_python.json | 15 +++++++++ .../meta/checkup_interactive_main_python.json | 11 +++++++ .../checkup_interactive_session_python.json | 16 +++++++++ .pdd/meta/checkup_planner_python.json | 11 +++++++ .pdd/meta/checkup_prompt_apply_python.json | 13 ++++++++ .pdd/meta/checkup_prompt_main_python.json | 24 ++++++++++++++ .pdd/meta/checkup_report_python.json | 13 ++++++++ .pdd/meta/checkup_review_loop_python.json | 14 ++++---- .pdd/meta/checkup_simplify_claude_python.json | 13 ++++++++ .../meta/checkup_simplify_engines_python.json | 15 +++++++++ .pdd/meta/checkup_simplify_python.json | 15 +++++++++ .pdd/meta/checkup_tools_python.json | 11 +++++++ .../ci_detect_changed_modules_python.json | 13 ++++++++ .pdd/meta/ci_drift_heal_python.json | 4 +-- .pdd/meta/ci_validation_python.json | 17 ++++++++++ .pdd/meta/cli_branding_python.json | 11 +++++++ .pdd/meta/cli_detector_python.json | 13 ++++++++ .pdd/meta/cli_status_python.json | 13 ++++++++ .pdd/meta/cli_theme_python.json | 4 +-- .pdd/meta/cmd_test_main_python.json | 22 +++++++++++++ .pdd/meta/code_generator_main_python.json | 26 +++++++-------- .pdd/meta/code_generator_python.json | 14 ++++++++ .pdd/meta/codex_subscription_python.json | 13 ++++++++ .pdd/meta/commands_analysis_python.json | 22 +++++++++++++ .pdd/meta/commands_auth_python.json | 20 +++++++++++ .pdd/meta/commands_checkup_python.json | 10 +++--- .../commands_checkup_simplify_python.json | 15 +++++++++ .pdd/meta/commands_connect_python.json | 19 +++++++++++ .pdd/meta/commands_context_python.json | 16 +++++++++ .pdd/meta/commands_contracts_python.json | 13 ++++++++ .pdd/meta/commands_firecrawl_python.json | 13 ++++++++ .pdd/meta/commands_fix_python.json | 18 ++++++++++ .pdd/meta/commands_gate_python.json | 13 ++++++++ .pdd/meta/commands_generate_python.json | 24 ++++++++++++++ .pdd/meta/commands_maintenance_python.json | 23 +++++++++++++ .pdd/meta/commands_misc_python.json | 15 +++++++++ .pdd/meta/commands_modify_python.json | 16 ++++----- .pdd/meta/commands_prompt_python.json | 4 +-- .pdd/meta/commands_replay_python.json | 14 ++++++++ .pdd/meta/commands_report_python.json | 15 +++++++++ .pdd/meta/commands_sessions_python.json | 17 ++++++++++ .pdd/meta/commands_story_python.json | 16 +++++++++ .pdd/meta/commands_templates_python.json | 14 ++++++++ .pdd/meta/commands_utility_python.json | 19 +++++++++++ .pdd/meta/commands_which_python.json | 15 +++++++++ .pdd/meta/comment_line_python.json | 13 ++++++++ .pdd/meta/compressed_sync_context_python.json | 19 +++++++++++ .pdd/meta/config_resolution_python.json | 14 ++++++++ .pdd/meta/conflicts_in_prompts_python.json | 17 ++++++++++ .pdd/meta/conflicts_main_python.json | 18 ++++++++++ .pdd/meta/construct_paths_python.json | 14 ++++---- .pdd/meta/content_selector_python.json | 17 ++++++++++ .pdd/meta/context_audit_python.json | 6 ++-- .pdd/meta/context_generator_main_python.json | 23 +++++++++++++ .pdd/meta/context_generator_python.json | 22 +++++++++++++ .pdd/meta/context_snapshot_python.json | 5 +-- .pdd/meta/continue_generation_python.json | 19 +++++++++++ .pdd/meta/contract_check_python.json | 15 +++++++++ .pdd/meta/contract_ir_python.json | 13 ++++++++ .pdd/meta/core_cli_python.json | 16 +++++++++ .pdd/meta/core_cloud_python.json | 16 +++++---- .pdd/meta/core_dump_python.json | 14 ++++++++ .../meta/core_duplicate_cli_guard_python.json | 19 +++++++++++ .pdd/meta/core_errors_python.json | 14 ++++++++ .pdd/meta/core_remote_session_python.json | 15 +++++++++ .pdd/meta/core_utils_python.json | 14 ++++++++ .pdd/meta/coverage_contracts_python.json | 13 ++++++++ .pdd/meta/crash_main_python.json | 19 +++++++++++ .pdd/meta/detect_change_main_python.json | 19 +++++++++++ .pdd/meta/detect_change_python.json | 22 +++++++++++++ .pdd/meta/durable_sync_runner_python.json | 16 ++++----- .pdd/meta/edit_file_python.json | 11 +++++++ .pdd/meta/embed_retrieve_python.json | 15 +++++++++ .pdd/meta/evidence_manifest_python.json | 15 +++++++++ .pdd/meta/evidence_store_python.json | 13 ++++++++ .pdd/meta/extracts_prune_python.json | 17 ++++++++++ .pdd/meta/failure_classification_python.json | 4 +-- .pdd/meta/find_section_python.json | 13 ++++++++ .pdd/meta/firecrawl_cache_python.json | 15 +++++++++ .pdd/meta/fix_code_loop_python.json | 10 +++--- .pdd/meta/fix_code_module_errors_python.json | 17 ++++++++++ .pdd/meta/fix_error_loop_python.json | 33 ++++++++++++++----- .../fix_errors_from_unit_tests_python.json | 21 ++++++++++++ .pdd/meta/fix_focus_python.json | 16 +++++++++ .pdd/meta/fix_main_python.json | 23 +++++++++++++ .../fix_verification_errors_loop_python.json | 19 +++++++++++ .pdd/meta/fix_verification_errors_python.json | 19 +++++++++++ .pdd/meta/fix_verification_main_python.json | 19 +++++++++++ .pdd/meta/gate_policy_python.json | 13 ++++++++ .pdd/meta/generate_model_catalog_python.json | 13 ++++++++ .pdd/meta/generate_output_paths_python.json | 18 ++++++++++ .pdd/meta/generate_test_python.json | 26 +++++++++++++++ .pdd/meta/generation_completion_python.json | 13 ++++++++ .pdd/meta/get_comment_python.json | 6 ++-- .pdd/meta/get_extension_python.json | 16 +++++++++ .pdd/meta/get_jwt_token_python.json | 16 +++++++++ .pdd/meta/get_language_python.json | 15 +++++++++ .pdd/meta/get_lint_commands_python.json | 16 +++++++++ .pdd/meta/get_run_command_python.json | 16 +++++++++ .pdd/meta/get_test_command_python.json | 13 ++++---- .pdd/meta/git_porcelain_python.json | 15 +++++++++ .pdd/meta/git_update_python.json | 12 +++---- .pdd/meta/grounding_policy_python.json | 15 +++++++++ .pdd/meta/include_query_extractor_python.json | 19 +++++++++++ .pdd/meta/increase_tests_python.json | 18 ++++++++++ .../incremental_code_generator_python.json | 18 ++++++++++ .../incremental_prd_architecture_python.json | 19 +++++++++++ .pdd/meta/insert_includes_python.json | 19 +++++++++++ .pdd/meta/install_completion_python.json | 16 +++++++++ .pdd/meta/llm_invoke_python.json | 15 +++++---- .pdd/meta/load_prompt_template_python.json | 15 +++++++++ .pdd/meta/logo_animation_python.json | 15 +++++++++ .pdd/meta/metadata_sync_python.json | 22 ++++++------- .pdd/meta/model_tester_python.json | 15 +++++++++ .pdd/meta/one_session_sync_python.json | 20 +++++++++++ .pdd/meta/operation_log_python.json | 16 +++++++++ .pdd/meta/path_resolution_python.json | 15 +++++++++ .pdd/meta/pddrc_initializer_python.json | 13 ++++++++ .pdd/meta/pin_example_hack_python.json | 12 +++---- .pdd/meta/postprocess_0_python.json | 17 ++++++++++ .pdd/meta/postprocess_python.json | 18 ++++++++++ .pdd/meta/pre_checkup_gate_python.json | 21 ++++++++++++ .pdd/meta/preprocess_main_python.json | 22 +++++++++++++ .pdd/meta/preprocess_python.json | 14 ++++---- .pdd/meta/process_csv_change_python.json | 16 +++++++++ .pdd/meta/prompt_lint_python.json | 4 +-- .pdd/meta/prompt_repair_python.json | 19 +++++++++++ .pdd/meta/prompt_tester_python.json | 14 ++++++++ .pdd/meta/provider_manager_python.json | 12 +++---- .pdd/meta/pytest_output_python.json | 15 +++++++++ .pdd/meta/pytest_slicer_python.json | 15 +++++++++ .pdd/meta/python_env_detector_python.json | 13 ++++++++ .pdd/meta/reasoning_python.json | 13 ++++++++ .pdd/meta/remote_session_python.json | 18 ++++++++++ .pdd/meta/render_mermaid_python.json | 13 ++++++++ .pdd/meta/resolved_sync_unit_python.json | 15 +++++++++ .pdd/meta/routing_policy_python.json | 18 ++++++++++ .pdd/meta/run_generated_python.json | 11 +++++++ .pdd/meta/server_app_python.json | 18 ++++++++++ .pdd/meta/server_click_executor_python.json | 15 +++++++++ .pdd/meta/server_executor_python.json | 17 ++++++++++ .pdd/meta/server_jobs_python.json | 8 ++--- .pdd/meta/server_models_python.json | 18 ++++++++++ .../server_routes_architecture_python.json | 18 ++++++++++ .pdd/meta/server_routes_auth_python.json | 17 ++++++++++ .pdd/meta/server_routes_commands_python.json | 19 +++++++++++ .pdd/meta/server_routes_config_python.json | 17 ++++++++++ .pdd/meta/server_routes_extracts_python.json | 18 ++++++++++ .pdd/meta/server_routes_files_python.json | 18 ++++++++++ .pdd/meta/server_routes_prompts_python.json | 22 +++++++++++++ .pdd/meta/server_routes_websocket_python.json | 17 ++++++++++ .pdd/meta/server_security_python.json | 15 +++++++++ .pdd/meta/server_terminal_spawner_python.json | 15 +++++++++ .pdd/meta/server_token_counter_python.json | 15 +++++++++ .pdd/meta/setup_tool_python.json | 18 ++++++++++ .pdd/meta/split_main_python.json | 20 +++++++++++ .pdd/meta/split_python.json | 22 +++++++++++++ .pdd/meta/split_validation_python.json | 17 ++++++++++ .pdd/meta/story_coverage_python.json | 15 +++++++++ .pdd/meta/story_regression_gate_python.json | 15 +++++++++ .pdd/meta/story_regression_python.json | 17 ++++++++++ .pdd/meta/story_test_generator_python.json | 13 ++++++++ .pdd/meta/summarize_directory_python.json | 10 +++--- .pdd/meta/sync_animation_python.json | 8 ++--- .../meta/sync_determine_operation_python.json | 4 +-- .pdd/meta/sync_main_python.json | 24 ++++++++++++++ .pdd/meta/sync_orchestration_python.json | 29 ++++++++-------- .pdd/meta/sync_order_python.json | 18 ++++++++++ .pdd/meta/sync_tui_python.json | 4 +-- .pdd/meta/template_expander_python.json | 15 +++++++++ .pdd/meta/template_registry_python.json | 15 +++++++++ .pdd/meta/test_context_packer_python.json | 16 +++++++++ .pdd/meta/trace_main_python.json | 18 ++++++++++ .pdd/meta/trace_python.json | 19 +++++++++++ .pdd/meta/track_cost_python.json | 14 ++++---- .pdd/meta/unfinished_prompt_python.json | 17 ++++++++++ .pdd/meta/update_main_python.json | 28 ++++++++++++++++ .pdd/meta/update_model_costs_python.json | 15 +++++++++ .pdd/meta/update_prompt_python.json | 21 ++++++++++++ .pdd/meta/user_story_tests_python.json | 15 +++++++++ .../meta/validate_prompt_includes_python.json | 13 ++++++++ .pdd/meta/xml_tagger_python.json | 17 ++++++++++ 223 files changed, 3325 insertions(+), 254 deletions(-) create mode 100644 .pdd/meta/_keyring_timeout_python.json create mode 100644 .pdd/meta/agentic_architecture_python.json create mode 100644 .pdd/meta/agentic_change_python.json create mode 100644 .pdd/meta/agentic_common_python.json create mode 100644 .pdd/meta/agentic_common_worktree_python.json create mode 100644 .pdd/meta/agentic_crash_python.json create mode 100644 .pdd/meta/agentic_e2e_fix_python.json create mode 100644 .pdd/meta/agentic_fix_python.json create mode 100644 .pdd/meta/agentic_langtest_python.json create mode 100644 .pdd/meta/agentic_split_python.json create mode 100644 .pdd/meta/agentic_sync_python.json create mode 100644 .pdd/meta/agentic_test_generate_python.json create mode 100644 .pdd/meta/agentic_test_orchestrator_python.json create mode 100644 .pdd/meta/agentic_test_python.json create mode 100644 .pdd/meta/agentic_update_python.json create mode 100644 .pdd/meta/agentic_verify_python.json create mode 100644 .pdd/meta/api_contract_slicer_python.json create mode 100644 .pdd/meta/api_key_scanner_python.json create mode 100644 .pdd/meta/architecture_include_validation_python.json create mode 100644 .pdd/meta/auth_service_python.json create mode 100644 .pdd/meta/auto_deps_architecture_python.json create mode 100644 .pdd/meta/auto_deps_main_python.json create mode 100644 .pdd/meta/auto_include_python.json create mode 100644 .pdd/meta/auto_update_python.json create mode 100644 .pdd/meta/bug_main_python.json create mode 100644 .pdd/meta/bug_to_unit_test_python.json create mode 100644 .pdd/meta/change_main_python.json create mode 100644 .pdd/meta/change_python.json create mode 100644 .pdd/meta/checkup_agent_python.json create mode 100644 .pdd/meta/checkup_file_selection_python.json create mode 100644 .pdd/meta/checkup_gates_python.json create mode 100644 .pdd/meta/checkup_interactive_main_python.json create mode 100644 .pdd/meta/checkup_interactive_session_python.json create mode 100644 .pdd/meta/checkup_planner_python.json create mode 100644 .pdd/meta/checkup_prompt_apply_python.json create mode 100644 .pdd/meta/checkup_prompt_main_python.json create mode 100644 .pdd/meta/checkup_report_python.json create mode 100644 .pdd/meta/checkup_simplify_claude_python.json create mode 100644 .pdd/meta/checkup_simplify_engines_python.json create mode 100644 .pdd/meta/checkup_simplify_python.json create mode 100644 .pdd/meta/checkup_tools_python.json create mode 100644 .pdd/meta/ci_detect_changed_modules_python.json create mode 100644 .pdd/meta/ci_validation_python.json create mode 100644 .pdd/meta/cli_branding_python.json create mode 100644 .pdd/meta/cli_detector_python.json create mode 100644 .pdd/meta/cli_status_python.json create mode 100644 .pdd/meta/cmd_test_main_python.json create mode 100644 .pdd/meta/code_generator_python.json create mode 100644 .pdd/meta/codex_subscription_python.json create mode 100644 .pdd/meta/commands_analysis_python.json create mode 100644 .pdd/meta/commands_auth_python.json create mode 100644 .pdd/meta/commands_checkup_simplify_python.json create mode 100644 .pdd/meta/commands_connect_python.json create mode 100644 .pdd/meta/commands_context_python.json create mode 100644 .pdd/meta/commands_contracts_python.json create mode 100644 .pdd/meta/commands_firecrawl_python.json create mode 100644 .pdd/meta/commands_fix_python.json create mode 100644 .pdd/meta/commands_gate_python.json create mode 100644 .pdd/meta/commands_generate_python.json create mode 100644 .pdd/meta/commands_maintenance_python.json create mode 100644 .pdd/meta/commands_misc_python.json create mode 100644 .pdd/meta/commands_replay_python.json create mode 100644 .pdd/meta/commands_report_python.json create mode 100644 .pdd/meta/commands_sessions_python.json create mode 100644 .pdd/meta/commands_story_python.json create mode 100644 .pdd/meta/commands_templates_python.json create mode 100644 .pdd/meta/commands_utility_python.json create mode 100644 .pdd/meta/commands_which_python.json create mode 100644 .pdd/meta/comment_line_python.json create mode 100644 .pdd/meta/compressed_sync_context_python.json create mode 100644 .pdd/meta/config_resolution_python.json create mode 100644 .pdd/meta/conflicts_in_prompts_python.json create mode 100644 .pdd/meta/conflicts_main_python.json create mode 100644 .pdd/meta/content_selector_python.json create mode 100644 .pdd/meta/context_generator_main_python.json create mode 100644 .pdd/meta/context_generator_python.json create mode 100644 .pdd/meta/continue_generation_python.json create mode 100644 .pdd/meta/contract_check_python.json create mode 100644 .pdd/meta/contract_ir_python.json create mode 100644 .pdd/meta/core_cli_python.json create mode 100644 .pdd/meta/core_dump_python.json create mode 100644 .pdd/meta/core_duplicate_cli_guard_python.json create mode 100644 .pdd/meta/core_errors_python.json create mode 100644 .pdd/meta/core_remote_session_python.json create mode 100644 .pdd/meta/core_utils_python.json create mode 100644 .pdd/meta/coverage_contracts_python.json create mode 100644 .pdd/meta/crash_main_python.json create mode 100644 .pdd/meta/detect_change_main_python.json create mode 100644 .pdd/meta/detect_change_python.json create mode 100644 .pdd/meta/edit_file_python.json create mode 100644 .pdd/meta/embed_retrieve_python.json create mode 100644 .pdd/meta/evidence_manifest_python.json create mode 100644 .pdd/meta/evidence_store_python.json create mode 100644 .pdd/meta/extracts_prune_python.json create mode 100644 .pdd/meta/find_section_python.json create mode 100644 .pdd/meta/firecrawl_cache_python.json create mode 100644 .pdd/meta/fix_code_module_errors_python.json create mode 100644 .pdd/meta/fix_errors_from_unit_tests_python.json create mode 100644 .pdd/meta/fix_focus_python.json create mode 100644 .pdd/meta/fix_main_python.json create mode 100644 .pdd/meta/fix_verification_errors_loop_python.json create mode 100644 .pdd/meta/fix_verification_errors_python.json create mode 100644 .pdd/meta/fix_verification_main_python.json create mode 100644 .pdd/meta/gate_policy_python.json create mode 100644 .pdd/meta/generate_model_catalog_python.json create mode 100644 .pdd/meta/generate_output_paths_python.json create mode 100644 .pdd/meta/generate_test_python.json create mode 100644 .pdd/meta/generation_completion_python.json create mode 100644 .pdd/meta/get_extension_python.json create mode 100644 .pdd/meta/get_jwt_token_python.json create mode 100644 .pdd/meta/get_language_python.json create mode 100644 .pdd/meta/get_lint_commands_python.json create mode 100644 .pdd/meta/get_run_command_python.json create mode 100644 .pdd/meta/git_porcelain_python.json create mode 100644 .pdd/meta/grounding_policy_python.json create mode 100644 .pdd/meta/include_query_extractor_python.json create mode 100644 .pdd/meta/increase_tests_python.json create mode 100644 .pdd/meta/incremental_code_generator_python.json create mode 100644 .pdd/meta/incremental_prd_architecture_python.json create mode 100644 .pdd/meta/insert_includes_python.json create mode 100644 .pdd/meta/install_completion_python.json create mode 100644 .pdd/meta/load_prompt_template_python.json create mode 100644 .pdd/meta/logo_animation_python.json create mode 100644 .pdd/meta/model_tester_python.json create mode 100644 .pdd/meta/one_session_sync_python.json create mode 100644 .pdd/meta/operation_log_python.json create mode 100644 .pdd/meta/path_resolution_python.json create mode 100644 .pdd/meta/pddrc_initializer_python.json create mode 100644 .pdd/meta/postprocess_0_python.json create mode 100644 .pdd/meta/postprocess_python.json create mode 100644 .pdd/meta/pre_checkup_gate_python.json create mode 100644 .pdd/meta/preprocess_main_python.json create mode 100644 .pdd/meta/process_csv_change_python.json create mode 100644 .pdd/meta/prompt_repair_python.json create mode 100644 .pdd/meta/prompt_tester_python.json create mode 100644 .pdd/meta/pytest_output_python.json create mode 100644 .pdd/meta/pytest_slicer_python.json create mode 100644 .pdd/meta/python_env_detector_python.json create mode 100644 .pdd/meta/reasoning_python.json create mode 100644 .pdd/meta/remote_session_python.json create mode 100644 .pdd/meta/render_mermaid_python.json create mode 100644 .pdd/meta/resolved_sync_unit_python.json create mode 100644 .pdd/meta/routing_policy_python.json create mode 100644 .pdd/meta/run_generated_python.json create mode 100644 .pdd/meta/server_app_python.json create mode 100644 .pdd/meta/server_click_executor_python.json create mode 100644 .pdd/meta/server_executor_python.json create mode 100644 .pdd/meta/server_models_python.json create mode 100644 .pdd/meta/server_routes_architecture_python.json create mode 100644 .pdd/meta/server_routes_auth_python.json create mode 100644 .pdd/meta/server_routes_commands_python.json create mode 100644 .pdd/meta/server_routes_config_python.json create mode 100644 .pdd/meta/server_routes_extracts_python.json create mode 100644 .pdd/meta/server_routes_files_python.json create mode 100644 .pdd/meta/server_routes_prompts_python.json create mode 100644 .pdd/meta/server_routes_websocket_python.json create mode 100644 .pdd/meta/server_security_python.json create mode 100644 .pdd/meta/server_terminal_spawner_python.json create mode 100644 .pdd/meta/server_token_counter_python.json create mode 100644 .pdd/meta/setup_tool_python.json create mode 100644 .pdd/meta/split_main_python.json create mode 100644 .pdd/meta/split_python.json create mode 100644 .pdd/meta/split_validation_python.json create mode 100644 .pdd/meta/story_coverage_python.json create mode 100644 .pdd/meta/story_regression_gate_python.json create mode 100644 .pdd/meta/story_regression_python.json create mode 100644 .pdd/meta/story_test_generator_python.json create mode 100644 .pdd/meta/sync_main_python.json create mode 100644 .pdd/meta/sync_order_python.json create mode 100644 .pdd/meta/template_expander_python.json create mode 100644 .pdd/meta/template_registry_python.json create mode 100644 .pdd/meta/test_context_packer_python.json create mode 100644 .pdd/meta/trace_main_python.json create mode 100644 .pdd/meta/trace_python.json create mode 100644 .pdd/meta/unfinished_prompt_python.json create mode 100644 .pdd/meta/update_main_python.json create mode 100644 .pdd/meta/update_model_costs_python.json create mode 100644 .pdd/meta/update_prompt_python.json create mode 100644 .pdd/meta/user_story_tests_python.json create mode 100644 .pdd/meta/validate_prompt_includes_python.json create mode 100644 .pdd/meta/xml_tagger_python.json diff --git a/.pdd/meta/_keyring_timeout_python.json b/.pdd/meta/_keyring_timeout_python.json new file mode 100644 index 0000000000..acebdf0229 --- /dev/null +++ b/.pdd/meta/_keyring_timeout_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.248150+00:00", + "command": "fix", + "prompt_hash": "febb0f9fd9f1e5f011acb73b44124f44ab3d401d53dc317912518f0798a075ad", + "code_hash": "edf79dca88f4b80350a607c8978cbc74ed9b195eaa1e052172409d15529db1e1", + "example_hash": "41f83d5ef117caba86b788f69b519f7e88f3d7dc2a641a017d74a7cee9be6ed1", + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_architecture_orchestrator_python.json b/.pdd/meta/agentic_architecture_orchestrator_python.json index 492082f7d9..2e331a3b01 100644 --- a/.pdd/meta/agentic_architecture_orchestrator_python.json +++ b/.pdd/meta/agentic_architecture_orchestrator_python.json @@ -1,17 +1,20 @@ { - "pdd_version": "0.0.230", - "timestamp": "2026-05-07T22:56:39.108172+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.250822+00:00", "command": "fix", - "prompt_hash": "f00e7085128ae23be67d1969542748cee0b0035552a1bf9ee3601a7e4497a3d1", - "code_hash": "a782f86dda46bdb22d9dc90a48049428b07e38f791dc55c1ac10b47e78156eab", + "prompt_hash": "d54fc246924930ac8e4dd5332bb00618220b4526eda5bd5267634430da6c0698", + "code_hash": "72bdf8417b0f27eb676bdf858032368dc5325e076f665e8de46e080315d4dc37", "example_hash": "aad78130a96907c5d1bd197a7bca53d6d1bdcf5775776860993f9e5c68635867", "test_hash": "30049fa3b4706221c111095cbbb9992f3335bd9ec6d51d6068bcd0cc2f9cf9f5", "test_files": { "test_agentic_architecture_orchestrator.py": "30049fa3b4706221c111095cbbb9992f3335bd9ec6d51d6068bcd0cc2f9cf9f5" }, "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", - "context/python_preamble.prompt": "57a3e51f529024ec0cb9658cd6ac61a7c8051ba0c8e887b31cf00b2e78a07d83", - "context/render_mermaid_example.py": "193a57bc4191595f252881c016ba7168c27c27c01ff192128d98cf76ce5f842b" + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/render_mermaid_example.py": "193a57bc4191595f252881c016ba7168c27c27c01ff192128d98cf76ce5f842b", + "pdd/architecture_registry.py": "5722225846b9cc8189b410a78e5714b4f2916d5748271d27f6f738692429c309", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" } -} +} \ No newline at end of file diff --git a/.pdd/meta/agentic_architecture_python.json b/.pdd/meta/agentic_architecture_python.json new file mode 100644 index 0000000000..f4ceaa3086 --- /dev/null +++ b/.pdd/meta/agentic_architecture_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.251927+00:00", + "command": "fix", + "prompt_hash": "2c9c70c851e1af7c0af70a9c9ce960f96a6c3bcce7edadef570457bed96987d4", + "code_hash": "09dd7b12d48fc7c0c0888157a5b366c42a077cd21b880f477ec763bca06edf28", + "example_hash": "f82ea3f16297c0cd0f7993549054bc9213953ebe03144aa5abc7bd74ba707e13", + "test_hash": "c15c58d2200e68f2db1c31c387d5f7c992e89623e037f47cf37042a5a43484de", + "test_files": { + "test_agentic_architecture.py": "c15c58d2200e68f2db1c31c387d5f7c992e89623e037f47cf37042a5a43484de", + "test_agentic_architecture_orchestrator.py": "30049fa3b4706221c111095cbbb9992f3335bd9ec6d51d6068bcd0cc2f9cf9f5" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/agentic_bug_orchestrator_python.json b/.pdd/meta/agentic_bug_orchestrator_python.json index a28ea032b6..c3a6ad8cd9 100644 --- a/.pdd/meta/agentic_bug_orchestrator_python.json +++ b/.pdd/meta/agentic_bug_orchestrator_python.json @@ -1,20 +1,20 @@ { - "pdd_version": "0.0.236", - "timestamp": "2026-05-26T00:00:00.000000+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.253859+00:00", "command": "fix", - "prompt_hash": "d33d79202c9e395e9a2a43a67741d6578ca002d07dec20cdeec77f9af0849fd1", - "code_hash": "03f458276287612267b7a96b5cb2042df81fb6a15d57f531634094f5e921aef9", + "prompt_hash": "074d1786614ee59558833746bede5e9236a9ceba635c5d8eb477880ea17eb9fd", + "code_hash": "f04052d57db4963fbdab55cc1076d11f72e5e7a50c8c40a15e8d8266a6cd189c", "example_hash": "23b545fc0f892e14ee9660902d3f7e04893f0b793246c1ea9d559656fd39ffe6", - "test_hash": "781fe2b15c71d3098e06d8845e8e03255d547093f65cb81a7d0b769d6c1a14e7", + "test_hash": "b0b0448434f1a87c1beb56ed4411462091b96096f3d662eca706b336ac43d3bf", "test_files": { - "test_agentic_bug_orchestrator.py": "781fe2b15c71d3098e06d8845e8e03255d547093f65cb81a7d0b769d6c1a14e7", + "test_agentic_bug_orchestrator.py": "b0b0448434f1a87c1beb56ed4411462091b96096f3d662eca706b336ac43d3bf", "test_agentic_bug_orchestrator_1.py": "8085e2041355e53aef1709eeba3591fa0f7c512a637038b8c48d633e4cd07aa2", - "test_agentic_bug_orchestrator_step_comments.py": "693e1c1b571a1daee1013fb48bc8390f263a6544c163e3f55bcb60dafa1bb679" + "test_agentic_bug_orchestrator_step_comments.py": "d8b948bbe7f2ee02202cf54c28812a2e6eb85f398b0c50bd0b8e9d9387c3a5c8" }, "include_deps": { "context/agentic_bug_example.py": "96e35df4e8425a9173ff6a30281892c2bd8b81361cff72b732e488172ddf52f5", - "context/agentic_common_example.py": "113b5829cae3a9e38c362b74d5115ba09cab06c7be5831527d9829f97f7b3b7d", + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } -} +} \ No newline at end of file diff --git a/.pdd/meta/agentic_bug_python.json b/.pdd/meta/agentic_bug_python.json index 06e2e27fba..f26197387c 100644 --- a/.pdd/meta/agentic_bug_python.json +++ b/.pdd/meta/agentic_bug_python.json @@ -1,21 +1,22 @@ { - "pdd_version": "0.0.228", - "timestamp": "2026-05-26T00:00:00.000000+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.255134+00:00", "command": "regenerate-public", "prompt_hash": "e0bd2e856ac450d59c9b284919708dd8771379b5a868f237a36174bec4d77efe", - "code_hash": "cd8cbb5f532bb89bdee0487bdd541240d0bb050c78d541135e251c94addb52f6", - "example_hash": null, + "code_hash": "ff878e298b3e1eb0639f99e68c88bb3507074208773f94440d413099fe896dc1", + "example_hash": "96e35df4e8425a9173ff6a30281892c2bd8b81361cff72b732e488172ddf52f5", "test_hash": "d9a31f3d603ee36158bbb2341c9ab43ba71f1762cef29027940b35404abba585", "test_files": { "test_agentic_bug.py": "d9a31f3d603ee36158bbb2341c9ab43ba71f1762cef29027940b35404abba585", - "test_agentic_bug_orchestrator.py": "781fe2b15c71d3098e06d8845e8e03255d547093f65cb81a7d0b769d6c1a14e7", + "test_agentic_bug_orchestrator.py": "b0b0448434f1a87c1beb56ed4411462091b96096f3d662eca706b336ac43d3bf", "test_agentic_bug_orchestrator_1.py": "8085e2041355e53aef1709eeba3591fa0f7c512a637038b8c48d633e4cd07aa2", + "test_agentic_bug_orchestrator_step_comments.py": "d8b948bbe7f2ee02202cf54c28812a2e6eb85f398b0c50bd0b8e9d9387c3a5c8", "test_agentic_bug_step10_prompt.py": "cca4e817639dabd0afd5f805eb894b78decc1858472d114debf885ffacbdf3d2", - "test_agentic_bug_step11_prompt.py": "8b41000be193c0024d999dd6cf1bd9f2f4615692e1c6bc52d0c46a83b560427b", - "test_agentic_bug_step7_prompt.py": "60c139b52632113013e2e1ac5c77f13257d0d370fc2be61d2420522bf44c830a" + "test_agentic_bug_step11_prompt.py": "fffd3447622a9df074b2a310da27fc466d964813b692210daaa5aaf6c6d59f59", + "test_agentic_bug_step7_prompt.py": "376be9629d5928d1dd5b3245572af3c3e8799d66d59e7c933ab08c0405b64faf" }, "include_deps": { "context/agentic_bug_orchestrator_example.py": "23b545fc0f892e14ee9660902d3f7e04893f0b793246c1ea9d559656fd39ffe6", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } -} +} \ No newline at end of file diff --git a/.pdd/meta/agentic_change_orchestrator_python.json b/.pdd/meta/agentic_change_orchestrator_python.json index c1a7ee6dbd..a361725266 100644 --- a/.pdd/meta/agentic_change_orchestrator_python.json +++ b/.pdd/meta/agentic_change_orchestrator_python.json @@ -1,21 +1,22 @@ { - "pdd_version": "0.0.233", - "timestamp": "2026-05-26T00:00:00.000000+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.258693+00:00", "command": "fix", - "prompt_hash": "147aebab37557437b25ade6f4a78b72c77350aed19d5f1d6d900feeaf4eadca4", - "code_hash": "19d8f4174475e05699edd0de801f238b3df6edc799b1ee44c5367cbad978adce", + "prompt_hash": "c4a5d86036e7020281184875081fe00099168f15de45a3f6fe050b689193499f", + "code_hash": "0eb021e1a02844b18205300373b4f45033faffa90c2eb681754403d26b864ad0", "example_hash": "fceaa9e9326bc78d10c74e519d756a09235b9606aba7b6e513fd3e2ebc56b4a2", - "test_hash": "10833f31e7de88490aa42d807f609f8481bb567c55aea5172b91429e398a91c4", + "test_hash": "2143164ebab405ee47b64dc45ce6c52eb025a54340233bb749b7333aa40cfbdd", "test_files": { - "test_agentic_change_orchestrator.py": "10833f31e7de88490aa42d807f609f8481bb567c55aea5172b91429e398a91c4" + "test_agentic_change_orchestrator.py": "2143164ebab405ee47b64dc45ce6c52eb025a54340233bb749b7333aa40cfbdd" }, "include_deps": { - "context/construct_paths_example.py": "9fb88745a2a0e2834f9da30c2128a122fef4d5a74212ceacc5f9c3d9ddb9a8ca", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", - "pdd/agentic_common.py": "82e30c361de4d7b9a62928fe21d8f55df96691c461c73750b30595e3a04446f2", - "pdd/architecture_sync.py": "fb55dc87aed5eca7eb62918291a247f4f3cc6b67555cdc8c02e22ce90a980d70", - "pdd/preprocess.py": "f95eedec5bcb4ca505d8682d4a38ea5d4b3eb07ac1d52a38ebffa9f89941a92e", - "pdd/sync_order.py": "118e49a22b0be2ae3017fdfeb1e05715a878efb89fab7750868be2388f2eaad9" + "pdd/agentic_common.py": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", + "pdd/architecture_sync.py": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", + "pdd/pre_checkup_gate.py": "9ff0bbaa18c82cf4da836126861c40936a4555b8ff972f4bceee370492f37ace", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56", + "pdd/sync_order.py": "6cdaed3b56d9cc12f38ee5ac93b8623899372ea2d177c4f131ec258edb94d0dd" } -} +} \ No newline at end of file diff --git a/.pdd/meta/agentic_change_python.json b/.pdd/meta/agentic_change_python.json new file mode 100644 index 0000000000..30031ec686 --- /dev/null +++ b/.pdd/meta/agentic_change_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.259922+00:00", + "command": "fix", + "prompt_hash": "629db7a1468e83aa831209e199f3058e30d83a572304487b9fcc89c6abb5bbdb", + "code_hash": "3ef811c674502fe2038225a183bb25edd372c86f52ac2308261448d5127f92b0", + "example_hash": "a8308b2af708c804d626a4a96012c5a67f5bc6469e33857cafc07627213828d7", + "test_hash": "12f8826c496f290c152545546209de1f78787aad054e2b45b16443dfb8d80b04", + "test_files": { + "test_agentic_change.py": "12f8826c496f290c152545546209de1f78787aad054e2b45b16443dfb8d80b04", + "test_agentic_change_orchestrator.py": "2143164ebab405ee47b64dc45ce6c52eb025a54340233bb749b7333aa40cfbdd" + }, + "include_deps": { + "context/agentic_change_orchestrator_example.py": "fceaa9e9326bc78d10c74e519d756a09235b9606aba7b6e513fd3e2ebc56b4a2", + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_checkup_orchestrator_python.json b/.pdd/meta/agentic_checkup_orchestrator_python.json index 2322ad2d07..10fa7ebfdb 100644 --- a/.pdd/meta/agentic_checkup_orchestrator_python.json +++ b/.pdd/meta/agentic_checkup_orchestrator_python.json @@ -1,18 +1,18 @@ { - "pdd_version": "0.0.273", - "timestamp": "2026-06-13T18:03:20.500524+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.261978+00:00", "command": "example", - "prompt_hash": "74563384c8358e0cfb994bd2b5e37a93a478a64c3e83a7cd1a63fa44246258d5", - "code_hash": "2a29489d565b0ebf5ef1d353f0070e806f9f990cd1eedc1c547abb983ddf93c0", - "example_hash": "9290bba1f27a21c2a8603065864fd059de6fde22151d6f0062e813a48b91061a", - "test_hash": "40ab1539859560e07acc3b4f5ac70ddeaa30e37333a04658c43c40593b18d55c", + "prompt_hash": "f6ce089869d82405a523e00b735d95f9a6b36d26cdbf84858df60ec56d5ff234", + "code_hash": "743a47b8a779974079f0ae3bb77090e47b3bd87606ac73a58cbf71e8b645d52e", + "example_hash": "295a9ae294e22224d3c447f13c462854bfe4e526cebc89bcbba417ea514c7ef2", + "test_hash": "7bfdf5931599356de13b4129f62ad5ed7ae928e10ae391c88a2e16f62ebf8d5c", "test_files": { - "test_agentic_checkup_orchestrator.py": "40ab1539859560e07acc3b4f5ac70ddeaa30e37333a04658c43c40593b18d55c" + "test_agentic_checkup_orchestrator.py": "7bfdf5931599356de13b4129f62ad5ed7ae928e10ae391c88a2e16f62ebf8d5c" }, "include_deps": { "context/agentic_bug_orchestrator_example.py": "23b545fc0f892e14ee9660902d3f7e04893f0b793246c1ea9d559656fd39ffe6", - "context/agentic_common_example.py": "f9cdb30a932973d341b795faf510056b95573610af5ac48e3849cf42c205998e", - "context/agentic_e2e_fix_orchestrator_example.py": "182e33cbf3aa78dc177caead0bf7f9e827cc17f0f9ba7cc32c0dd027063bde64", + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_e2e_fix_orchestrator_example.py": "180cc2c4316b531586040d61fc5f82f1f605d5c5736fd23bad63a889ac0b7d1e", "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", "context/preprocess_example.py": "e7082a4a9ef830048ff32ed774a3e74da1cf4662a22115e6bd5543e1b9cdbf43" diff --git a/.pdd/meta/agentic_checkup_python.json b/.pdd/meta/agentic_checkup_python.json index c5d85cd57e..ad8345d301 100644 --- a/.pdd/meta/agentic_checkup_python.json +++ b/.pdd/meta/agentic_checkup_python.json @@ -1,22 +1,23 @@ { - "pdd_version": "0.0.288.dev0", - "timestamp": "2026-06-26T22:58:40.678699+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.263817+00:00", "command": "test", - "prompt_hash": "86d6766af5e844962a3160de65f69177aab4146060461afeb674ad489ab71e26", - "code_hash": "30e37254c3d5721d0b7a43c023a677b670219b072fd0fa7a64990ce0c13fd175", + "prompt_hash": "4b264564e6cdff492415aff67a3da2362933b7d802a1e1470d31d973d7d7566a", + "code_hash": "d5b79fc009c5f935fd7fe70b2b2517f4f1f5c2c02a1231bf1d87ddbc4baba042", "example_hash": "57c5e8ae852946da79151ab49e44400f2c093bf6f8add0bf25a01c9872a13101", "test_hash": "4d7a9c10ba2f9925f7b567f885b6dd67dd48aa3e8757e347ddad9e6c7b6f3e02", "test_files": { "test_agentic_checkup.py": "4d7a9c10ba2f9925f7b567f885b6dd67dd48aa3e8757e347ddad9e6c7b6f3e02", - "test_agentic_checkup_orchestrator.py": "e37ccd4a0ffaa25a52f1374c570bb4fa9b4a69bd95a9a766f4e60d97a4dfb5fe" + "test_agentic_checkup_orchestrator.py": "7bfdf5931599356de13b4129f62ad5ed7ae928e10ae391c88a2e16f62ebf8d5c", + "test_agentic_checkup_step5_pass_evidence.py": "a9d5ac08e1cbf1326ab352cffdfbb3bc84c280327b70413ef6f982860bf89e44" }, "include_deps": { "context/agentic_change_example.py": "a8308b2af708c804d626a4a96012c5a67f5bc6469e33857cafc07627213828d7", "context/agentic_checkup_orchestrator_example.py": "295a9ae294e22224d3c447f13c462854bfe4e526cebc89bcbba417ea514c7ef2", "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", - "context/agentic_sync_example.py": "9bcc2f199a1463e8c424d8210ea6d5f34ad6fb5fcb1022aa879a9ecba0f8d5d6", + "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", "context/checkup_review_loop_example.py": "b392eaa48f9bd84660d4a2aaec04c5237a7791059c6ffd64288b34eadce686bb", "context/ci_validation_example.py": "06b910b216f68af58862e76712ccf82bae1bdf87f3fa95b043408fb079f45ce0", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } -} +} \ No newline at end of file diff --git a/.pdd/meta/agentic_common_python.json b/.pdd/meta/agentic_common_python.json new file mode 100644 index 0000000000..b28b2dc8af --- /dev/null +++ b/.pdd/meta/agentic_common_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.267777+00:00", + "command": "fix", + "prompt_hash": "300127d8bb7c0a9c48aecad8b02a9b9e1bead782d778e5e70f97b6f827eab308", + "code_hash": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", + "example_hash": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "test_hash": "9007b43d4423a3d90be314d02afbd04b6a95537d3a19c19bfeef5a0a6c8232c0", + "test_files": { + "test_agentic_common.py": "9007b43d4423a3d90be314d02afbd04b6a95537d3a19c19bfeef5a0a6c8232c0", + "test_agentic_common_issue_813_anthropic_api_key_oauth_shadow.py": "4207732c6fb0e88b5be1fe632acd087f0b992e1ac7498dff036a0b9b9ea72138", + "test_agentic_common_worktree.py": "16fb52387d635f1bbccbac20d08ef5b5d878021b70fc1ad79e5d36664df2b9a9" + }, + "include_deps": { + "context/_keyring_timeout_example.py": "41f83d5ef117caba86b788f69b519f7e88f3d7dc2a641a017d74a7cee9be6ed1", + "context/api_key_scanner_example.py": "4b9f880a30445f25edffc394857ae0c218097726c41ab996a03fcbc4350b5482", + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/agentic_common.py": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_common_worktree_python.json b/.pdd/meta/agentic_common_worktree_python.json new file mode 100644 index 0000000000..01e061654a --- /dev/null +++ b/.pdd/meta/agentic_common_worktree_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.268540+00:00", + "command": "fix", + "prompt_hash": "97ac2a6c3d3d0eff020a5508dddfe4c8e58530594d49372922a605fbcdeb9541", + "code_hash": "9d54b21c1801d1f708340917eeb265435d968698392e501c2d8d214da6f4ee3f", + "example_hash": null, + "test_hash": "16fb52387d635f1bbccbac20d08ef5b5d878021b70fc1ad79e5d36664df2b9a9", + "test_files": { + "test_agentic_common_worktree.py": "16fb52387d635f1bbccbac20d08ef5b5d878021b70fc1ad79e5d36664df2b9a9" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_crash_python.json b/.pdd/meta/agentic_crash_python.json new file mode 100644 index 0000000000..5fa8d7d21e --- /dev/null +++ b/.pdd/meta/agentic_crash_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.269693+00:00", + "command": "fix", + "prompt_hash": "54aa28a454f27094d61f5ab79d3e52e379ffc0d3e240df1d7746e220846d6757", + "code_hash": "78b5f9651c10d3ce474ff62b32f8f8953135847858fd6873c0824356068285c4", + "example_hash": "4a79b152db522063ccf099eca0419b419a656f168839d197f85781ae4fe1b5f6", + "test_hash": "413b22619a7acea9126f270cd4b99da1cf27108bd1d56a92e32cd58594c4b0c8", + "test_files": { + "test_agentic_crash.py": "413b22619a7acea9126f270cd4b99da1cf27108bd1d56a92e32cd58594c4b0c8" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/get_run_command_example.py": "4d187e844adb255c2738274556f4828728d0d73d84ebf8bda885d51d4be9414f", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "prompts/agentic_crash_explore_LLM.prompt": "1a63eddbf271c5976841de535dcc518db58a5b4b5a61b7a6c08472458ad9ed3c" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_e2e_fix_orchestrator_python.json b/.pdd/meta/agentic_e2e_fix_orchestrator_python.json index 3714c38a3a..d4b27d6899 100644 --- a/.pdd/meta/agentic_e2e_fix_orchestrator_python.json +++ b/.pdd/meta/agentic_e2e_fix_orchestrator_python.json @@ -1,19 +1,19 @@ { - "pdd_version": "0.0.257", - "timestamp": "2026-06-02T05:35:45.135425+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.272493+00:00", "command": "test", - "prompt_hash": "3db920baa54e4b2a67fee0dc24de08e26087b7f60ce9687b2fd7261b14f1f621", - "code_hash": "605779bd8be274f89d045972413cd2ce394cf4e6c808e24bfd7f4674fb10b17d", - "example_hash": "8cc5f11b0430113ad52c918cdbabafe254cf01667eb66e1ac8837f5cea965024", - "test_hash": "f15b0ccd990d7ab178700b28211c4e46f29f991500272c73583149309572607c", + "prompt_hash": "52d67e9a9cb487be694437418a6663657780aeb10c5196218f2c3bcf11bf1b09", + "code_hash": "ad8df3444101a4ac3297db032f33b875c581c91fc615bc0f602a89b53113920e", + "example_hash": "180cc2c4316b531586040d61fc5f82f1f605d5c5736fd23bad63a889ac0b7d1e", + "test_hash": "b481eb0460268575f6816a13711049ca5df749871185df6759ece7d7bd5f6fcd", "test_files": { - "test_agentic_e2e_fix_orchestrator.py": "f15b0ccd990d7ab178700b28211c4e46f29f991500272c73583149309572607c", + "test_agentic_e2e_fix_orchestrator.py": "b481eb0460268575f6816a13711049ca5df749871185df6759ece7d7bd5f6fcd", "test_agentic_e2e_fix_orchestrator_resume_prompt.py": "8e29ea7eb6330f75fa53b2699663f417b43cb063b8ac5613f34cbf0a6ceaa917" }, "include_deps": { "context/agentic_bug_orchestrator_example.py": "23b545fc0f892e14ee9660902d3f7e04893f0b793246c1ea9d559656fd39ffe6", - "context/agentic_common_example.py": "113b5829cae3a9e38c362b74d5115ba09cab06c7be5831527d9829f97f7b3b7d", - "context/agentic_e2e_fix_orchestrator_example.py": "8cc5f11b0430113ad52c918cdbabafe254cf01667eb66e1ac8837f5cea965024", + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_e2e_fix_orchestrator_example.py": "180cc2c4316b531586040d61fc5f82f1f605d5c5736fd23bad63a889ac0b7d1e", "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", "context/agentic_test_orchestrator_example.py": "473901f6f62844c81a047fa69387c4116d91a522c62d5c6ad30188e2e99dfaa5", "context/change/16/fix_error_loop.py": "01872cfcc6c3f5095551acd109e06b35ece96c15ca75dcf40ac395c3ed867e40", diff --git a/.pdd/meta/agentic_e2e_fix_python.json b/.pdd/meta/agentic_e2e_fix_python.json new file mode 100644 index 0000000000..ead2594bbb --- /dev/null +++ b/.pdd/meta/agentic_e2e_fix_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.273641+00:00", + "command": "fix", + "prompt_hash": "fc0a1a8955b1b6c6848985a7a037eb7595bc0134357d599cd34c85cf41f885be", + "code_hash": "ab0b08e59e59b52431e7f4ba6a2b39f6267c7a43d0d45bf3573596c96649a57c", + "example_hash": "79fd30a0fa6d8a5b9e23b34f7328ba3f95089a0ebb83e8244dae79ea68cff33a", + "test_hash": "5e5507d9fc6035164d78e1dcf3ccf983694c4057185d5644ff47f7743e052c3b", + "test_files": { + "test_agentic_e2e_fix.py": "5e5507d9fc6035164d78e1dcf3ccf983694c4057185d5644ff47f7743e052c3b", + "test_agentic_e2e_fix_orchestrator.py": "b481eb0460268575f6816a13711049ca5df749871185df6759ece7d7bd5f6fcd", + "test_agentic_e2e_fix_orchestrator_resume_prompt.py": "8e29ea7eb6330f75fa53b2699663f417b43cb063b8ac5613f34cbf0a6ceaa917", + "test_agentic_e2e_fix_step10_prompt.py": "dd9b37268f192ce23b07dc9af157e4fcb1554c457adff67b719a00c89a8c7e63" + }, + "include_deps": { + "context/agentic_e2e_fix_orchestrator_example.py": "180cc2c4316b531586040d61fc5f82f1f605d5c5736fd23bad63a889ac0b7d1e", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_fix_python.json b/.pdd/meta/agentic_fix_python.json new file mode 100644 index 0000000000..05bdd79a42 --- /dev/null +++ b/.pdd/meta/agentic_fix_python.json @@ -0,0 +1,20 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.274810+00:00", + "command": "fix", + "prompt_hash": "2aa547410ad5be7b47e1e69dcbfad7abb844b621a432730f24886a1e5014f350", + "code_hash": "10fad4819034f9b2553c2fc584d2e977f490b1de43533219545a71ae19904179", + "example_hash": "407a024fcba9402e00b401477725ae72b1de718ab59bea29b69509a0b15f621f", + "test_hash": "635df7c7b087344d3c138b16af299aa878a0cb9d958d7ac22a91915fa64735ba", + "test_files": { + "test_agentic_fix.py": "635df7c7b087344d3c138b16af299aa878a0cb9d958d7ac22a91915fa64735ba" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", + "context/get_run_command_example.py": "4d187e844adb255c2738274556f4828728d0d73d84ebf8bda885d51d4be9414f", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_langtest_python.json b/.pdd/meta/agentic_langtest_python.json new file mode 100644 index 0000000000..31445fe8de --- /dev/null +++ b/.pdd/meta/agentic_langtest_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.275276+00:00", + "command": "fix", + "prompt_hash": "e63708a4640607ed61932a11b5c2f5c15a46e00fc1ad2113b9622414c4950f28", + "code_hash": "7cb0be38d526d0a630500185427a9f76666d2b79385f7333a7608eb1fb33cfc9", + "example_hash": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "test_hash": "9a745d3b5cb6721be2993e2b49bb25a860d269de30168dc6d5850097937de1c2", + "test_files": { + "test_agentic_langtest.py": "9a745d3b5cb6721be2993e2b49bb25a860d269de30168dc6d5850097937de1c2" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_multishot_python.json b/.pdd/meta/agentic_multishot_python.json index 9445b3f464..4380f3da6c 100644 --- a/.pdd/meta/agentic_multishot_python.json +++ b/.pdd/meta/agentic_multishot_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.274", - "timestamp": "2026-06-16T01:03:00.882482+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.276849+00:00", "command": "test", - "prompt_hash": "235a4c06a65d4cc3e27794db81c846aa988e056bf1896a559c3fbf9645f84fbb", + "prompt_hash": "0628511c4ecc1d928041296b13623b351b51e9596bd46485162b9b6a966b0073", "code_hash": "ecd0bfb52beb8172399b6da05f17d4ea308b22c4a5b10d5a32a98829c6e48edc", "example_hash": "7708a23b090f5cde8ace2e358fd35f4efcfcb3b96910d8e86aa0f6ab09447167", "test_hash": "8e1a14a52353590059265c6e59540c64b68ff650fb605fc78e831d6b3bac6d1d", @@ -11,7 +11,7 @@ }, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", - "pdd/agentic_common.py": "922f9c3b140c10e04d8ddbacf50f1399df7fda0a5e6dbb99f6e0af0bb131d1dd", + "pdd/agentic_common.py": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", "pdd/failure_classification.py": "0675857d23f52e447f15ace22ec37c2f003a61d3c810254c8547129c29d697ff" } } \ No newline at end of file diff --git a/.pdd/meta/agentic_split_orchestrator_python.json b/.pdd/meta/agentic_split_orchestrator_python.json index 703edbae6c..d54a4daa2e 100644 --- a/.pdd/meta/agentic_split_orchestrator_python.json +++ b/.pdd/meta/agentic_split_orchestrator_python.json @@ -1,16 +1,22 @@ { - "pdd_version": "0.0.234", - "timestamp": "2026-05-12T02:53:56.081699+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.279678+00:00", "command": "fix", - "prompt_hash": "a9590c82b2b9cbbc9c39e64580662b9e1d1b779225cdbb0e798fd81d92257b6d", - "code_hash": "daaa0487f9e9538f2536f8e3ed061efb0068b83cda8bcae9aa993a0d1955baf4", + "prompt_hash": "e942762fcacc211d4f279733aa9a37f836c102b7bed4143cc5e6aa9f6d1236ae", + "code_hash": "6e36d867ae932aa29f1aff078182179b6b0d3ddb86a99ddc5e3e23deaa110549", "example_hash": "3f521ffaf006c3ab7fad663edc7d4bcc89f4bafe81ba43e760e9fe99ef7ea46c", "test_hash": "be3d9b082577fc7fac8bae292c109ab2d9df7b376f775825168c69941c10bbb7", "test_files": { "test_agentic_split_orchestrator.py": "be3d9b082577fc7fac8bae292c109ab2d9df7b376f775825168c69941c10bbb7" }, "include_deps": { + "context/agentic_test_orchestrator_example.py": "473901f6f62844c81a047fa69387c4116d91a522c62d5c6ad30188e2e99dfaa5", "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", - "context/python_preamble.prompt": "57a3e51f529024ec0cb9658cd6ac61a7c8051ba0c8e887b31cf00b2e78a07d83" + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/agentic_common.py": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", + "pdd/agentic_common_worktree.py": "9d54b21c1801d1f708340917eeb265435d968698392e501c2d8d214da6f4ee3f", + "pdd/architecture_sync.py": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56", + "pdd/split_validation.py": "e51a9512fc4cedbe362f25da3c97c23a89057901bff10c6b04eeefe77b79dafe" } } \ No newline at end of file diff --git a/.pdd/meta/agentic_split_python.json b/.pdd/meta/agentic_split_python.json new file mode 100644 index 0000000000..23d345b9ce --- /dev/null +++ b/.pdd/meta/agentic_split_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.281302+00:00", + "command": "fix", + "prompt_hash": "216d6d2604fc6c2374b755be22a60994e34a73be331114b13ac7d8c5a5abc87e", + "code_hash": "044ff030cd6896b3a20507b6797033c2784fc2c17826024a304cea446d255038", + "example_hash": "25283e3976254717458001e7bcd058ae7d62af3c867a78e6206a9135091dadf4", + "test_hash": "8f3f1396daa31100274cd8a0c232b3bece8c2d46a1c0bc996f978fbeff739fa3", + "test_files": { + "test_agentic_split.py": "8f3f1396daa31100274cd8a0c232b3bece8c2d46a1c0bc996f978fbeff739fa3", + "test_agentic_split_orchestrator.py": "be3d9b082577fc7fac8bae292c109ab2d9df7b376f775825168c69941c10bbb7", + "test_agentic_split_real.py": "d68ec06d83da47934743bdb963d4eee4c7a46ee6ec5abedcee6c12b4bf022c15", + "test_agentic_split_v2.py": "a609bc2db408f669da9f3429b2389c244e53ca5c53da834a032ca2e2e9820ff5" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_split_orchestrator_example.py": "3f521ffaf006c3ab7fad663edc7d4bcc89f4bafe81ba43e760e9fe99ef7ea46c", + "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/agentic_common_worktree.py": "9d54b21c1801d1f708340917eeb265435d968698392e501c2d8d214da6f4ee3f" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_sync_python.json b/.pdd/meta/agentic_sync_python.json new file mode 100644 index 0000000000..6765f7ad0f --- /dev/null +++ b/.pdd/meta/agentic_sync_python.json @@ -0,0 +1,25 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.283498+00:00", + "command": "fix", + "prompt_hash": "b46925c0018d0b91841bee732c5da57c6d1d71b8b848d57543005120a6885f08", + "code_hash": "b98bddf2b04560eb402d856aa6dd9a7077e731123edfb3bf9cbd80064681d879", + "example_hash": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", + "test_hash": "5365a19305e0fc78b8fb0f21b6b7a16c4ed405bd75e32c3e6ddcd1e814b6a15b", + "test_files": { + "test_agentic_sync.py": "5365a19305e0fc78b8fb0f21b6b7a16c4ed405bd75e32c3e6ddcd1e814b6a15b", + "test_agentic_sync_fallback_realgit.py": "cad09f7c0d18a9983a106fbb688db018ff52a2ba46e5cbd3dfd86389ab1b32de", + "test_agentic_sync_mocked_e2e.py": "a8adc991a2796b06a4f8ef59c531eab632350784ca7961d1282d4fa8424b38fe", + "test_agentic_sync_nearest_config.py": "afbed1e4021978e9b7480f4bb80bdba737c4a0adffb7768b3191b14bbce6ca19", + "test_agentic_sync_runner.py": "daf57f3bb02e467053caf2fa5ac5b8d11cdad4db74016ee521d6e6f64c283621" + }, + "include_deps": { + "context/agentic_change_example.py": "a8308b2af708c804d626a4a96012c5a67f5bc6469e33857cafc07627213828d7", + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_sync_runner_example.py": "fcb36209abb5ab882ad551754fb574d62509c968f8c564e18163be7f2b7ef35a", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/sync_order_example.py": "b4eb1e167e7604c7dbac703bdcba7287188fa9d2d5ef6d490216d003cdc542fa" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_sync_runner_python.json b/.pdd/meta/agentic_sync_runner_python.json index 9a568d6680..7fe64b7703 100644 --- a/.pdd/meta/agentic_sync_runner_python.json +++ b/.pdd/meta/agentic_sync_runner_python.json @@ -1,21 +1,21 @@ { - "pdd_version": "0.0.275.dev3", - "timestamp": "2026-06-16T01:31:18.161464+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.285767+00:00", "command": "fix", - "prompt_hash": "0784d6ff7f749b74e6938bfdd945a1cf97aed961ebea4bf3849fe512bf7163f9", - "code_hash": "587d51aaed8470de39bbefbb0882f481f269431cca8b50e45b22e90dbd2eb695", + "prompt_hash": "1039b82c0ca610342a21046297c0798f86a4f99217ebe2725b147a7f3cca2401", + "code_hash": "572f865d1bdbddf4827d5f308eb72030c3ed085c4f570284cbda8c961d01af2d", "example_hash": "fcb36209abb5ab882ad551754fb574d62509c968f8c564e18163be7f2b7ef35a", - "test_hash": "781deb083113a3c96b990501f24cdf41e0742190be5cfbe85553639c25e62e22", + "test_hash": "daf57f3bb02e467053caf2fa5ac5b8d11cdad4db74016ee521d6e6f64c283621", "test_files": { - "test_agentic_sync_runner.py": "781deb083113a3c96b990501f24cdf41e0742190be5cfbe85553639c25e62e22" + "test_agentic_sync_runner.py": "daf57f3bb02e467053caf2fa5ac5b8d11cdad4db74016ee521d6e6f64c283621" }, "include_deps": { "context/agentic_change_example.py": "a8308b2af708c804d626a4a96012c5a67f5bc6469e33857cafc07627213828d7", - "context/agentic_common_example.py": "f9cdb30a932973d341b795faf510056b95573610af5ac48e3849cf42c205998e", + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", "context/agentic_test_orchestrator_example.py": "473901f6f62844c81a047fa69387c4116d91a522c62d5c6ad30188e2e99dfaa5", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/sync_order_example.py": "b4eb1e167e7604c7dbac703bdcba7287188fa9d2d5ef6d490216d003cdc542fa" } -} +} \ No newline at end of file diff --git a/.pdd/meta/agentic_test_generate_python.json b/.pdd/meta/agentic_test_generate_python.json new file mode 100644 index 0000000000..bca10c01ba --- /dev/null +++ b/.pdd/meta/agentic_test_generate_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.286814+00:00", + "command": "fix", + "prompt_hash": "028c512165adf77ee126b1d10be74c53df990fbf4206b919b42cfae966d4d13f", + "code_hash": "5c34b242014d6cc56a1e9504bc649032ecea24fc09c50754afad2d421053020e", + "example_hash": "5b021f33624a41accf5463ea151ccfaab9f9f268ca95fb21c94e3f0dda9f4661", + "test_hash": "29a887349d31f0a1233ae1375be56dd4530bf8d9d1ca8c38917091f105fc1024", + "test_files": { + "test_agentic_test_generate.py": "29a887349d31f0a1233ae1375be56dd4530bf8d9d1ca8c38917091f105fc1024" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_test_orchestrator_python.json b/.pdd/meta/agentic_test_orchestrator_python.json new file mode 100644 index 0000000000..3e54fb2f28 --- /dev/null +++ b/.pdd/meta/agentic_test_orchestrator_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.287938+00:00", + "command": "fix", + "prompt_hash": "eff9420f13230d7a96a6ff94c36ab5b49cfe47d9cbc47a1cb1532a566aaa0239", + "code_hash": "38435707d35f64e685a3789ff8752768ffcfffed927af11b9dd90ba08ab93ff9", + "example_hash": "473901f6f62844c81a047fa69387c4116d91a522c62d5c6ad30188e2e99dfaa5", + "test_hash": "b352fb8c22880f5c95e74f3b2b7a89251fd13e6563ff2ec550f8e4f5e34807dd", + "test_files": { + "test_agentic_test_orchestrator.py": "b352fb8c22880f5c95e74f3b2b7a89251fd13e6563ff2ec550f8e4f5e34807dd" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/pytest_output_example.py": "6f0cd68e3c4440081267c716651caec4fbdd7d9c4516f967517f02ae2a853920" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_test_python.json b/.pdd/meta/agentic_test_python.json new file mode 100644 index 0000000000..a3a171fe35 --- /dev/null +++ b/.pdd/meta/agentic_test_python.json @@ -0,0 +1,20 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.289069+00:00", + "command": "fix", + "prompt_hash": "ddab846232bad2745161f117a908bb88f9050878fe61f944e7e18dece79dad61", + "code_hash": "e9834cc73b9d125bc46354b262a9b17067150f044055edda5529adb695a0b372", + "example_hash": "1d8b490a2b0ff53a8b786c6c95faeecc4efd0becf837b35273508bae19fac3ab", + "test_hash": "03163284790ecd0c014d9df0311a75a03243f4355430dcaf8080bfaaa6b321d4", + "test_files": { + "test_agentic_test.py": "03163284790ecd0c014d9df0311a75a03243f4355430dcaf8080bfaaa6b321d4", + "test_agentic_test_generate.py": "29a887349d31f0a1233ae1375be56dd4530bf8d9d1ca8c38917091f105fc1024", + "test_agentic_test_orchestrator.py": "b352fb8c22880f5c95e74f3b2b7a89251fd13e6563ff2ec550f8e4f5e34807dd" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_test_orchestrator_example.py": "473901f6f62844c81a047fa69387c4116d91a522c62d5c6ad30188e2e99dfaa5", + "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_update_python.json b/.pdd/meta/agentic_update_python.json new file mode 100644 index 0000000000..a9b27200c7 --- /dev/null +++ b/.pdd/meta/agentic_update_python.json @@ -0,0 +1,20 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.290902+00:00", + "command": "fix", + "prompt_hash": "3f8ff49dcf8a62526143f7d4c06c0780cc0180351c1da693eeb28e3b37d3aa0c", + "code_hash": "f0bd8afbbb4cbbc8dcde8116061a09fdd7a888daa540b48eb46b360153a5c6a4", + "example_hash": "967254cd1c636ac5ba09afa0446312ffc1f28d3041ed453a4c6588c931f722c4", + "test_hash": "45d00c80b59d0037dbb148b706fe758a789fa9a5fce1129a675cee1b4dfc99bd", + "test_files": { + "test_agentic_update.py": "45d00c80b59d0037dbb148b706fe758a789fa9a5fce1129a675cee1b4dfc99bd" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/agentic_common.py": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", + "pdd/sync_order.py": "6cdaed3b56d9cc12f38ee5ac93b8623899372ea2d177c4f131ec258edb94d0dd", + "prompts/agentic_update_LLM.prompt": "0fe3ff3c55d39cd68d3f4d1105e156a608c8668a27c3d81efea5289b2430ba17" + } +} \ No newline at end of file diff --git a/.pdd/meta/agentic_verify_python.json b/.pdd/meta/agentic_verify_python.json new file mode 100644 index 0000000000..43347b3772 --- /dev/null +++ b/.pdd/meta/agentic_verify_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.291780+00:00", + "command": "fix", + "prompt_hash": "9c95d066438cd9e009e36875214172c588a7db46d1805dddbc74018b930a179f", + "code_hash": "ede66dcf689550aaebe8991e6ba90eaa2502315789de90faaa507c8944cb5060", + "example_hash": "1a64161baccfc035ffbd73bf99cc1888d28d8d714a49deb01a75918e3b9732f8", + "test_hash": "e16430d5639d9871b7ae2ac231fc8db00a51fbd7dcfb9d5b8f39a4dc66f4c145", + "test_files": { + "test_agentic_verify.py": "e16430d5639d9871b7ae2ac231fc8db00a51fbd7dcfb9d5b8f39a4dc66f4c145" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "prompts/agentic_verify_explore_LLM.prompt": "c02f53aa9b003f4acd9f2cff09cccf166993e0ffe21a012caa0fdf52ac8d105c" + } +} \ No newline at end of file diff --git a/.pdd/meta/api_contract_slicer_python.json b/.pdd/meta/api_contract_slicer_python.json new file mode 100644 index 0000000000..7e2323591b --- /dev/null +++ b/.pdd/meta/api_contract_slicer_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.292235+00:00", + "command": "fix", + "prompt_hash": "79768843f184f50c60dd2caf94ba173f115b04a4f6fc50eca601de9008c710d5", + "code_hash": "0170b39f8ac42c0ff86ea426c1f98449158a5f3321474422a252397283c77f3e", + "example_hash": "9eec29df45d8ce83496ddb65c5954d475e5eebf33c94914e1a716b124b6ba3ad", + "test_hash": "d8deb0dc7223949fbd47486d05adc7764e17d42a5b6e52a3e9de5daaed28f637", + "test_files": { + "test_api_contract_slicer.py": "d8deb0dc7223949fbd47486d05adc7764e17d42a5b6e52a3e9de5daaed28f637" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/api_key_scanner_python.json b/.pdd/meta/api_key_scanner_python.json new file mode 100644 index 0000000000..75c2c83e00 --- /dev/null +++ b/.pdd/meta/api_key_scanner_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.292556+00:00", + "command": "fix", + "prompt_hash": "4d93f1716d60a12ac6a6730482c96f1a7242ecdc57b9d3c28dafada9c137c4b9", + "code_hash": "45cc7a5ac182630ed7a04980cff5430658cc79989904264cf1556c04311a0610", + "example_hash": "4b9f880a30445f25edffc394857ae0c218097726c41ab996a03fcbc4350b5482", + "test_hash": "28e01c935c44ef9838aae8b9e88d013f74ae6edd4a8f64a999e620bf7896b6dc", + "test_files": { + "test_api_key_scanner.py": "28e01c935c44ef9838aae8b9e88d013f74ae6edd4a8f64a999e620bf7896b6dc" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/architecture_include_validation_python.json b/.pdd/meta/architecture_include_validation_python.json new file mode 100644 index 0000000000..7bb31c633e --- /dev/null +++ b/.pdd/meta/architecture_include_validation_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.293341+00:00", + "command": "fix", + "prompt_hash": "bba83e01cec00a1a3c1fb7a9f174705bd169cb7c42cff69ac9a83d611a53e957", + "code_hash": "b412fed88e36c21751565c0c94a9dfe314c3a280d04ab0a2e82f1ea17ca81c08", + "example_hash": null, + "test_hash": "2b53d831392eefeb2d7cc83c38e683c96b107e9c11ef9ff880e5ec8c5976bc43", + "test_files": { + "test_architecture_include_validation.py": "2b53d831392eefeb2d7cc83c38e683c96b107e9c11ef9ff880e5ec8c5976bc43" + }, + "include_deps": { + "context/architecture_registry_example.py": "5eff404eddcfb9d898df972d703013b7124d352e5fe898a1977d7986ef17ed1e", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0" + } +} \ No newline at end of file diff --git a/.pdd/meta/architecture_sync_python.json b/.pdd/meta/architecture_sync_python.json index 1bdd459444..eeb79bab78 100644 --- a/.pdd/meta/architecture_sync_python.json +++ b/.pdd/meta/architecture_sync_python.json @@ -1,10 +1,10 @@ { - "pdd_version": "0.0.268", - "timestamp": "2026-06-09T23:29:39.505348+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.294436+00:00", "command": "example", "prompt_hash": "2fb502ebb1466361da7c064975239bc9e9bbf2e80bb3b2da95e3027862f2dd99", "code_hash": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", - "example_hash": "6e1f65de35fcf1dbd0def81710da6f378495b37187eb01cd01ef43f662d9f1ba", + "example_hash": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", "test_hash": "55cd4d0fc35712f39a23dc54f2dea33011e608861616a389a877436e90f48342", "test_files": { "test_architecture_sync.py": "55cd4d0fc35712f39a23dc54f2dea33011e608861616a389a877436e90f48342" diff --git a/.pdd/meta/auth_service_python.json b/.pdd/meta/auth_service_python.json new file mode 100644 index 0000000000..100b2d7596 --- /dev/null +++ b/.pdd/meta/auth_service_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.295456+00:00", + "command": "fix", + "prompt_hash": "f78505eb6667a42e4995a591d706334faf15fa7f164b659877bb5c7f343d2df0", + "code_hash": "a4b689e00ad7106bb775f1b365d67b3d5106f5e4c7021d7ac751468652d7693c", + "example_hash": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "test_hash": "82838601cf50ad78807070aa07b5433bbd964c49102ba3215a696e8d7683522c", + "test_files": { + "test_auth_service.py": "82838601cf50ad78807070aa07b5433bbd964c49102ba3215a696e8d7683522c" + }, + "include_deps": { + "context/_keyring_timeout_example.py": "41f83d5ef117caba86b788f69b519f7e88f3d7dc2a641a017d74a7cee9be6ed1", + "context/get_jwt_token_example.py": "76a87c8257cb1f4cfdc2edff6225c752432afb3a5e352fcb016d08d8eae16e01", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/auto_deps_architecture_python.json b/.pdd/meta/auto_deps_architecture_python.json new file mode 100644 index 0000000000..40edef93fe --- /dev/null +++ b/.pdd/meta/auto_deps_architecture_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.296571+00:00", + "command": "fix", + "prompt_hash": "2e31837c35515ab3922301a394228ab699115c424a9b3a0a42bb26e673544893", + "code_hash": "d20e3525f49abb1c4d4d923ed619e9f0b26cb29cbca12df2f22479b8d3926a44", + "example_hash": null, + "test_hash": "9d72534ca9044063c7c75a4ab8f5addac9f49e0e27248a055541e15aec8b4cd7", + "test_files": { + "test_auto_deps_architecture.py": "9d72534ca9044063c7c75a4ab8f5addac9f49e0e27248a055541e15aec8b4cd7" + }, + "include_deps": { + "context/architecture_registry_example.py": "5eff404eddcfb9d898df972d703013b7124d352e5fe898a1977d7986ef17ed1e", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/sync_order_example.py": "b4eb1e167e7604c7dbac703bdcba7287188fa9d2d5ef6d490216d003cdc542fa" + } +} \ No newline at end of file diff --git a/.pdd/meta/auto_deps_main_python.json b/.pdd/meta/auto_deps_main_python.json new file mode 100644 index 0000000000..744683730a --- /dev/null +++ b/.pdd/meta/auto_deps_main_python.json @@ -0,0 +1,23 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.298791+00:00", + "command": "fix", + "prompt_hash": "e2de0f2e2216a9bd6a1f257ec4f0964dbf2cd67a8d0295cf9701820dc8cc287b", + "code_hash": "b5df06f550c4dc0151af20f911eb19552d494cfb9853a7f35bd67c096a40581a", + "example_hash": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", + "test_hash": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20", + "test_files": { + "test_auto_deps_main.py": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/insert_includes_example.py": "c304bf4656f75fa26192c92b3eb0422a903d8a1bc82dda3158dc9f184b337873", + "context/operation_log_example.py": "2660def7012d9b79bad3db33cf399ac603cc1c35dff0b064cbdd2638a013de1d", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/auto_deps_architecture.py": "d20e3525f49abb1c4d4d923ed619e9f0b26cb29cbca12df2f22479b8d3926a44", + "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", + "pdd/validate_prompt_includes.py": "fa97b72a58534e255768634f928f4cfdd2130a7a4d8b296da3eefdf77d47855b" + } +} \ No newline at end of file diff --git a/.pdd/meta/auto_include_python.json b/.pdd/meta/auto_include_python.json new file mode 100644 index 0000000000..02da6911ff --- /dev/null +++ b/.pdd/meta/auto_include_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.300193+00:00", + "command": "fix", + "prompt_hash": "47d0a02c54c54e2b9835a96321fe76ae283abc9467c20af1e5363312b960e27c", + "code_hash": "5bcd43f2318cb317a8fe7cbbc510a8bd020ddf8b2b6cfa5dafbf128b37586b8a", + "example_hash": "0c278ed716298149777bc7082827eb8aa6d80dac264c66b6cded6871232f2df7", + "test_hash": "96b40dc287e8ae63ceb00676026e6f89254d83fd27e3955315bfaa6c5080b689", + "test_files": { + "test_auto_include.py": "96b40dc287e8ae63ceb00676026e6f89254d83fd27e3955315bfaa6c5080b689" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/summarize_directory_example.py": "99f9b729f3b148891d471e79e5a29e67e39c30aad8e9922ced2982ca02b158ea", + "context/embed_retrieve_example.py": "17920a5c72ada21b31f6df15d9ad156d67ebaf8f141c3839b068d9379360cd84", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f" + } +} \ No newline at end of file diff --git a/.pdd/meta/auto_update_python.json b/.pdd/meta/auto_update_python.json new file mode 100644 index 0000000000..db7ce41e1a --- /dev/null +++ b/.pdd/meta/auto_update_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.300548+00:00", + "command": "fix", + "prompt_hash": "072c1e4211367cc131c7aef9b844c8590e3a0642afafda817bfbf19179227e80", + "code_hash": "0945c48a916c2783701c5aac8da7e2f033c4a2c0939f1cb96dab30bdb39eadba", + "example_hash": "4fc8ab0da96c0e8abe793d195dbc64b6b9771631be818eecde059769e5914fc9", + "test_hash": "5b414e3024d1db83dcc7def5e91579e8dcf2f7b414b3173b8dfb053364d2afdf", + "test_files": { + "test_auto_update.py": "5b414e3024d1db83dcc7def5e91579e8dcf2f7b414b3173b8dfb053364d2afdf" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/bug_main_python.json b/.pdd/meta/bug_main_python.json new file mode 100644 index 0000000000..0877f35b29 --- /dev/null +++ b/.pdd/meta/bug_main_python.json @@ -0,0 +1,21 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.301922+00:00", + "command": "fix", + "prompt_hash": "9eb6e4dcae71fb61e683ddfe07362e0e6668ffa18eca3160585781e6e4201df2", + "code_hash": "add508e807f11ea3bf90b1a1038307c2f491fdc7cbf338029e097b987aff3ae2", + "example_hash": "662ecde39d05a5345533c4ae74c6b1031f016916ec2ff4764d34a26f7ec26172", + "test_hash": "12d1162a4485fd58f8c122251c4929884b3f6ec4a60943c5f1fa6315698f01e1", + "test_files": { + "test_bug_main.py": "12d1162a4485fd58f8c122251c4929884b3f6ec4a60943c5f1fa6315698f01e1" + }, + "include_deps": { + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/agentic_bug_example.py": "96e35df4e8425a9173ff6a30281892c2bd8b81361cff72b732e488172ddf52f5", + "context/bug_to_unit_test_example.py": "ab1d665923937f6599f78c0cac82f5d7c04a7afa092e7767d67e417e067a8817", + "context/cloud_function_call.py": "62ac7724ce2e3eddbba2b743bd7aa5790dbed34eae01e77e0252c4cc6358c95e", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/get_jwt_token_example.py": "76a87c8257cb1f4cfdc2edff6225c752432afb3a5e352fcb016d08d8eae16e01" + } +} \ No newline at end of file diff --git a/.pdd/meta/bug_to_unit_test_python.json b/.pdd/meta/bug_to_unit_test_python.json new file mode 100644 index 0000000000..22f5f5fd06 --- /dev/null +++ b/.pdd/meta/bug_to_unit_test_python.json @@ -0,0 +1,20 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.303093+00:00", + "command": "fix", + "prompt_hash": "f0c0cb57741620d320c1e7248e44e033b6c929187186268bd636538ea3f2efb3", + "code_hash": "06842a372290a414035bcf89c011ff457e111d14a253c2a4dc4a6516b9040add", + "example_hash": "ab1d665923937f6599f78c0cac82f5d7c04a7afa092e7767d67e417e067a8817", + "test_hash": "6a131f5326feadafe8520656f49bb2eba8bc07cf9dd4453149dcb02646e82aef", + "test_files": { + "test_bug_to_unit_test.py": "6a131f5326feadafe8520656f49bb2eba8bc07cf9dd4453149dcb02646e82aef" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/unfinished_prompt_example.py": "5d4d74064e5b845391f035fb8631903ec2f39a54a90713f9c13dc24d2eb73c4f", + "context/continue_generation_example.py": "29c33a967bcdf4fa0037e1c7b0ec699c00027606dbe9d93fa4d1434f9c16c19e", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/postprocess_example.py": "b98362e6ffb84ae7826dad27d0854e30706f3993266314439859986b32ecd0bd" + } +} \ No newline at end of file diff --git a/.pdd/meta/change_main_python.json b/.pdd/meta/change_main_python.json new file mode 100644 index 0000000000..7f1244d64c --- /dev/null +++ b/.pdd/meta/change_main_python.json @@ -0,0 +1,21 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.304544+00:00", + "command": "fix", + "prompt_hash": "e8db62d56db28f59310080c7bd87fce607be32fb8d92f03b562b7ef73d52a376", + "code_hash": "a350dfbafdcee8275e86760417f194ea3154b17417a32137a49f36f2e3e182de", + "example_hash": "990b2dfc2b9ef2f1871cb4fe1b7a01d5d6f4f4f54f9a6a95fc3661c679802d42", + "test_hash": "5a1fd84f2fd4f14538fab3571575552c12089e687e8d24080fa2934d52f0d890", + "test_files": { + "test_change_main.py": "5a1fd84f2fd4f14538fab3571575552c12089e687e8d24080fa2934d52f0d890" + }, + "include_deps": { + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/change_example.py": "cc5f850c8e41a8c5b82c94b6667975d1811dff1f51888bb8caf4ff69815f8352", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", + "context/process_csv_change_example.py": "c7cf31cd55d5312b5398d3d518eddd33354fa184d0e92c6cf926a3c71d018227", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/validate_prompt_includes.py": "fa97b72a58534e255768634f928f4cfdd2130a7a4d8b296da3eefdf77d47855b" + } +} \ No newline at end of file diff --git a/.pdd/meta/change_python.json b/.pdd/meta/change_python.json new file mode 100644 index 0000000000..cbe45a7d2f --- /dev/null +++ b/.pdd/meta/change_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.306496+00:00", + "command": "fix", + "prompt_hash": "78e1d54b350c8096a9652d858a7f41406b224756dc55a4894c1d97df37f14698", + "code_hash": "d66d22f9ef9e6a80574d91b115bf72aac534d238dd8a8085d5744e1a8c1562a3", + "example_hash": "cc5f850c8e41a8c5b82c94b6667975d1811dff1f51888bb8caf4ff69815f8352", + "test_hash": "1bab7571601fbb32b1d86fd1100129c94cf40a09b9d26b3890249d76d398a74c", + "test_files": { + "test_change.py": "1bab7571601fbb32b1d86fd1100129c94cf40a09b9d26b3890249d76d398a74c", + "test_change_call_site_and_retry.py": "2c668ab36b5e09dd57231484932b3221d2d8bd1e4fa70836eefe2f3d5551d7db", + "test_change_main.py": "5a1fd84f2fd4f14538fab3571575552c12089e687e8d24080fa2934d52f0d890" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/change/12/initial_postprocess.py": "845d5ada84654630518eda1f06e372bd2af87a230077ce8078efc543b9286714", + "context/change/14/initial_change.py": "fec3fba35a4710e02375bdb017bcf33882c2a3b690733fc9d5c6021c1602785c", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_agent_python.json b/.pdd/meta/checkup_agent_python.json new file mode 100644 index 0000000000..56d8df9555 --- /dev/null +++ b/.pdd/meta/checkup_agent_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.306916+00:00", + "command": "fix", + "prompt_hash": "653a638d7dbede994e83a15482b572c27f5d5a27df3e8f20ad244544a5a9318e", + "code_hash": "d091af7573d71153ee8106191cd8e732bd098cfcfb50f40e8bdbb4acb41ec41d", + "example_hash": null, + "test_hash": "9ee77b78b481814461321d77954839bfbbf1190be0677a15b4fb5d2ce9da7914", + "test_files": { + "test_checkup_agent.py": "9ee77b78b481814461321d77954839bfbbf1190be0677a15b4fb5d2ce9da7914" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/checkup_file_selection_python.json b/.pdd/meta/checkup_file_selection_python.json new file mode 100644 index 0000000000..e0e9b9d7b6 --- /dev/null +++ b/.pdd/meta/checkup_file_selection_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.307283+00:00", + "command": "fix", + "prompt_hash": "f49ed34a0a7be2d0539d9b5b1cbd1f8aec20537a4f5a4b2d97d514ebbdfe0f51", + "code_hash": "2139db4e6952575d8a094096f37687c5918619cf5a5733bd7d47d27717be9ab2", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_gates_python.json b/.pdd/meta/checkup_gates_python.json new file mode 100644 index 0000000000..c391b9ef42 --- /dev/null +++ b/.pdd/meta/checkup_gates_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.308370+00:00", + "command": "fix", + "prompt_hash": "40c44f6befb609de46b5441e473bdedf9192cf820b13639ed278252a542c79ab", + "code_hash": "b6086954a93e0495661e6ca39d96b3079b928d13308bf0fcd6a16b1e0b5f511c", + "example_hash": "fb271f80bd2c0b2e1aebecec9c99431d4319d0d3121167a8cb8fb65154f7f284", + "test_hash": "a0e5bba5c85bbda53c497a838b7154a5629c6f82d7cfd71035aa15706b5b6b28", + "test_files": { + "test_checkup_gates.py": "a0e5bba5c85bbda53c497a838b7154a5629c6f82d7cfd71035aa15706b5b6b28" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_interactive_main_python.json b/.pdd/meta/checkup_interactive_main_python.json new file mode 100644 index 0000000000..0a00105fec --- /dev/null +++ b/.pdd/meta/checkup_interactive_main_python.json @@ -0,0 +1,11 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.308604+00:00", + "command": "fix", + "prompt_hash": "5abaf9a3e2e5ff24c024ff03f07ccc9c7686a13cd389f0e98870a78fd97cb1cb", + "code_hash": "82ef9d91f959a52ba334a15c89b9fa94afa164d6b69eae0f0c029579163035f2", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/checkup_interactive_session_python.json b/.pdd/meta/checkup_interactive_session_python.json new file mode 100644 index 0000000000..b5fd3bfdca --- /dev/null +++ b/.pdd/meta/checkup_interactive_session_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.309079+00:00", + "command": "fix", + "prompt_hash": "56f9f2ddfd309e93c49b22a6b319618f4e9254f433bceb6ff9e10aaa1c4951f6", + "code_hash": "9a06207e7c3a1c8c53f38c9029cf9fb24baf3a8f8be6170eee420aadf604bde7", + "example_hash": "711e6ebd025da577a9f5e94f6d347deeb5636c7a61051547b8daade00b40edae", + "test_hash": "83db77cb2a2bdc260952041dc31c6524c2904eef1aa62e02dc371a948058213e", + "test_files": { + "test_checkup_interactive_session.py": "83db77cb2a2bdc260952041dc31c6524c2904eef1aa62e02dc371a948058213e", + "test_checkup_interactive_session_spike.py": "324c842cc728489e21cd5e26a2c2e7feede37e18a7a7fb9cdb2b03f996de36c4" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_planner_python.json b/.pdd/meta/checkup_planner_python.json new file mode 100644 index 0000000000..06046b9d07 --- /dev/null +++ b/.pdd/meta/checkup_planner_python.json @@ -0,0 +1,11 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.309307+00:00", + "command": "fix", + "prompt_hash": "6d3d2dc712729d789b6293c33c411fb8cff975dcb17ebbd38ea7138b876ce241", + "code_hash": "2ab02a1c2c971b16b700c6ecf1062eafcaa053aec8c8cd43c9864a6cad5dbd1b", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/checkup_prompt_apply_python.json b/.pdd/meta/checkup_prompt_apply_python.json new file mode 100644 index 0000000000..a29db2941a --- /dev/null +++ b/.pdd/meta/checkup_prompt_apply_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.309570+00:00", + "command": "fix", + "prompt_hash": "95685575e722bfed5574086d8e01f31ec743e6f4046b101032748e7848efb14c", + "code_hash": "d72f795e03a2eb9b60023ee3f2e23975d10a61c7deb0daeb319030e5a1f92206", + "example_hash": null, + "test_hash": "c699ccf181590954e7155624838dd6d0f39cd81f958f18cd7e11276046e9282d", + "test_files": { + "test_checkup_prompt_apply.py": "c699ccf181590954e7155624838dd6d0f39cd81f958f18cd7e11276046e9282d" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/checkup_prompt_main_python.json b/.pdd/meta/checkup_prompt_main_python.json new file mode 100644 index 0000000000..3fbd8d0ea6 --- /dev/null +++ b/.pdd/meta/checkup_prompt_main_python.json @@ -0,0 +1,24 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.311541+00:00", + "command": "fix", + "prompt_hash": "a7e1a43ec7e38aecd73d9b4acaf142413c48d6df461d524c122f22bac10df8ef", + "code_hash": "538367ba6b7fa74d9f86ba6d1235219598f7a124c58cf00ad0abf6cf027526dc", + "example_hash": "04845b3c70203df3ce51d3c3a1aaac61bcb0089d2af3f7d92af73b7f923ab32c", + "test_hash": "81f5c4befae10e8f4f1078f2e772db1646dd43c1bd24c541e8687a4659e760af", + "test_files": { + "test_checkup_prompt_main.py": "81f5c4befae10e8f4f1078f2e772db1646dd43c1bd24c541e8687a4659e760af" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/construct_paths.py": "7b42a002e4ecc27be4d517cbc07f1fc9425e795d4918714f382d2ed5ddd00eab", + "pdd/context_snapshot_policy.py": "a292f02584ff67ef491d97d914d8282db4e6694aed97e140480064851953760e", + "pdd/contract_check.py": "5c168f2c45b6754acce9b7fd50730c1832053df160b5de88f064061333b84f1a", + "pdd/coverage_contracts.py": "dc209452c683697866e133c5673a2caba1828c9e4836e012f277e0250a643c0c", + "pdd/evidence_store.py": "eccc499c6f076b52e4b481a07904b9390120e52c49cb2479adbdf5eb433df14c", + "pdd/gate_main.py": "8281d282d9ad62dc01c92c4f520ea0be70e5fba50281d18fd4111445ebfd613a", + "pdd/prompt_lint.py": "df85f363082925c714e23be8d7b2e941d62a8542a3370a2581d16780cef1474e", + "pdd/source_set_model.py": "72465c576d85e606d557e602ea78c8dc58646455a429a8dfa4e7b66da22210fa", + "pdd/user_story_tests.py": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_report_python.json b/.pdd/meta/checkup_report_python.json new file mode 100644 index 0000000000..dd50b28abc --- /dev/null +++ b/.pdd/meta/checkup_report_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.311833+00:00", + "command": "fix", + "prompt_hash": "2b1ffbc310805ac63bcd051f10ce03159534752ea729a6b11e91bf8e27400188", + "code_hash": "1dbd1ce70b5bad244814044cda35b08e31f3830ade98aa7abadf55913d156fc8", + "example_hash": null, + "test_hash": "cfd2b272dc93e2d58657a6e07aec68cc14f8883ed1354900cea3545cc4eab203", + "test_files": { + "test_checkup_report.py": "cfd2b272dc93e2d58657a6e07aec68cc14f8883ed1354900cea3545cc4eab203" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/checkup_review_loop_python.json b/.pdd/meta/checkup_review_loop_python.json index 1710fae580..0463002e29 100644 --- a/.pdd/meta/checkup_review_loop_python.json +++ b/.pdd/meta/checkup_review_loop_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.288.dev0", - "timestamp": "2026-06-26T23:09:14.954776+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.314978+00:00", "command": "fix", - "prompt_hash": "05eafdbdedc8b12e80c5ac70d860902292ba364ff2dcf5da19959e9862ace5ef", - "code_hash": "a49524b05e78c8969518f44a654f9f90e869225fe94f7ad5d7ed3c675c1eead7", + "prompt_hash": "a4ec8ed0458adb258d495ea6444d014d4898e004814ee8447359816658d26be5", + "code_hash": "8addb7e16d4f1b4e36ce8214748c8fdae9db53a09802d29a872b046d687bf2d1", "example_hash": "b392eaa48f9bd84660d4a2aaec04c5237a7791059c6ffd64288b34eadce686bb", - "test_hash": "e388afeff3508ef3e87be8261fe8400d7cdec20eabcb4b31717e755019bc41fa", + "test_hash": "6b357b123dd5b1a72c4231def4042c8a7cb748c3fbb84680a4159e6256511730", "test_files": { - "test_checkup_review_loop.py": "e388afeff3508ef3e87be8261fe8400d7cdec20eabcb4b31717e755019bc41fa" + "test_checkup_review_loop.py": "6b357b123dd5b1a72c4231def4042c8a7cb748c3fbb84680a4159e6256511730" }, "include_deps": { "context/agentic_change_example.py": "a8308b2af708c804d626a4a96012c5a67f5bc6469e33857cafc07627213828d7", @@ -16,4 +16,4 @@ "context/agentic_e2e_fix_orchestrator_example.py": "180cc2c4316b531586040d61fc5f82f1f605d5c5736fd23bad63a889ac0b7d1e", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } -} +} \ No newline at end of file diff --git a/.pdd/meta/checkup_simplify_claude_python.json b/.pdd/meta/checkup_simplify_claude_python.json new file mode 100644 index 0000000000..d57e62572c --- /dev/null +++ b/.pdd/meta/checkup_simplify_claude_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.315826+00:00", + "command": "fix", + "prompt_hash": "d3587f96ae7eee752af14011c3ecceb94fb0c20691132fe5ef7aaf82caa8e083", + "code_hash": "0dd6846d6b5e9ec63ac71fa6474eb84f06bc2dbb5f168e9c01eeeb2eee7f1c7a", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_simplify_engines_python.json b/.pdd/meta/checkup_simplify_engines_python.json new file mode 100644 index 0000000000..6f86e335a2 --- /dev/null +++ b/.pdd/meta/checkup_simplify_engines_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.316384+00:00", + "command": "fix", + "prompt_hash": "0eaef948b5e725a8dbc1a14b1240b52946cbb9893401d0a6b001004c93267086", + "code_hash": "9009191475a97901ad9b4eac39a682f55b4789297022d9c3752aba4126ea3230", + "example_hash": null, + "test_hash": "e1ae900756abdba9805b2e50002811d22e48afb3ebe3fea3b60b7cd003487984", + "test_files": { + "test_checkup_simplify_engines.py": "e1ae900756abdba9805b2e50002811d22e48afb3ebe3fea3b60b7cd003487984" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_simplify_python.json b/.pdd/meta/checkup_simplify_python.json new file mode 100644 index 0000000000..2a13346ec9 --- /dev/null +++ b/.pdd/meta/checkup_simplify_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.316852+00:00", + "command": "fix", + "prompt_hash": "3a0b375fbd9294ef119fed542d772ad16485ab579fe15fd55619e363d08e10a2", + "code_hash": "6ec8b1694b0ec8c9955261fff159b1a86397d54f24a0f95ea5243ac9cbd6df7f", + "example_hash": null, + "test_hash": null, + "test_files": { + "test_checkup_simplify_engines.py": "e1ae900756abdba9805b2e50002811d22e48afb3ebe3fea3b60b7cd003487984" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/checkup_tools_python.json b/.pdd/meta/checkup_tools_python.json new file mode 100644 index 0000000000..235d3cf996 --- /dev/null +++ b/.pdd/meta/checkup_tools_python.json @@ -0,0 +1,11 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.317113+00:00", + "command": "fix", + "prompt_hash": "df087676e5581e2e05a7d6daa036b5e1113cccd5c837a1b4a3508b890e1da118", + "code_hash": "d11c11dc9670827619d71214c4d7d3b6535c13460a67d8290af83c34f050e757", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/ci_detect_changed_modules_python.json b/.pdd/meta/ci_detect_changed_modules_python.json new file mode 100644 index 0000000000..5151de47cb --- /dev/null +++ b/.pdd/meta/ci_detect_changed_modules_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.318042+00:00", + "command": "fix", + "prompt_hash": "ef30764861a3080d2fb093ca747f86a3f46bba733a0cdc6a5634efc1b36a73a2", + "code_hash": "0d77f7c40e1498558218ea0d552f09bc9d02e128be4dca789f6b0f13dfc76007", + "example_hash": "bb23030662fb2337011f8e8db75b455be5d1b2f66cda50685d35745a31f362b2", + "test_hash": "592936e3f208b79f1b4410e9766a7ba16971c11eea7f9b26e1221550972b37f4", + "test_files": { + "test_ci_detect_changed_modules.py": "592936e3f208b79f1b4410e9766a7ba16971c11eea7f9b26e1221550972b37f4" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/ci_drift_heal_python.json b/.pdd/meta/ci_drift_heal_python.json index c40747ccc7..5b2caa4e9d 100644 --- a/.pdd/meta/ci_drift_heal_python.json +++ b/.pdd/meta/ci_drift_heal_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.296.dev0", - "timestamp": "2026-07-09T11:32:55.747881+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.320450+00:00", "command": "fix", "prompt_hash": "09fe741d2541f30d7ece2447ba91fa8cf91bb4c9ef937810abe6e622649b68df", "code_hash": "4866e9be8fc9513c4d7a5cd03c5eff4c7ebb3a639024c91682322d77f462b94a", diff --git a/.pdd/meta/ci_validation_python.json b/.pdd/meta/ci_validation_python.json new file mode 100644 index 0000000000..669af9f04a --- /dev/null +++ b/.pdd/meta/ci_validation_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.321560+00:00", + "command": "fix", + "prompt_hash": "6627ace940bcffc3b9cd754c83014635f2949a11c32f6b133e6f209ddc908d3b", + "code_hash": "01935b7b312fcbc3a1812290f6d69fe5d65ddf3530f546c8da729bb8d6a3aeae", + "example_hash": "06b910b216f68af58862e76712ccf82bae1bdf87f3fa95b043408fb079f45ce0", + "test_hash": "c68f729059f3bf0409b5e7f797b2fcf61fc463502e07d8c4db79b10be6a7fb7f", + "test_files": { + "test_ci_validation.py": "c68f729059f3bf0409b5e7f797b2fcf61fc463502e07d8c4db79b10be6a7fb7f" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/ci_validation_example.py": "06b910b216f68af58862e76712ccf82bae1bdf87f3fa95b043408fb079f45ce0", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/cli_branding_python.json b/.pdd/meta/cli_branding_python.json new file mode 100644 index 0000000000..2f1d81baf7 --- /dev/null +++ b/.pdd/meta/cli_branding_python.json @@ -0,0 +1,11 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.321850+00:00", + "command": "fix", + "prompt_hash": "2b1c46c67c15235c43a7aacbaba313a0a98dc21383d3b91507173eabfd588fba", + "code_hash": "fc9056e722b00d532aafc3c051eab4d6ba3f5cb7a3aaa4492194202cc8000a24", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/cli_detector_python.json b/.pdd/meta/cli_detector_python.json new file mode 100644 index 0000000000..e3f120dbff --- /dev/null +++ b/.pdd/meta/cli_detector_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.322290+00:00", + "command": "fix", + "prompt_hash": "4bcecc483a368af1d6dc9d9f0b12e608e760b179c5b03c2c4d866a06cbdbe59b", + "code_hash": "78b4e788b206d2902296351faecfcc8e2ced44b9dbc696837b4c7bd45f1fce7a", + "example_hash": "db64a53121864c633ba1586f1af491ae7cc617c10cf4c477a7e6d262f676cd23", + "test_hash": "6b92fed161723fc46aa7aef74efa1af0506c8da8f8085e87cd20cef9297f2724", + "test_files": { + "test_cli_detector.py": "6b92fed161723fc46aa7aef74efa1af0506c8da8f8085e87cd20cef9297f2724" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/cli_status_python.json b/.pdd/meta/cli_status_python.json new file mode 100644 index 0000000000..628488df9a --- /dev/null +++ b/.pdd/meta/cli_status_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.322589+00:00", + "command": "fix", + "prompt_hash": "121ff116fa307d8034c8f8826f0e1382fd6467fe4eb9d5ef480030901d114e57", + "code_hash": "9aacc600635c5a2e6f5d9b2ef028ba701b3d6605b23e497aabc0382a6d8ef1d5", + "example_hash": null, + "test_hash": "968db7dd3edc563c9f7b43ea83dab5030150bcb29e74f60c5ba84e066ee29069", + "test_files": { + "test_cli_status.py": "968db7dd3edc563c9f7b43ea83dab5030150bcb29e74f60c5ba84e066ee29069" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/cli_theme_python.json b/.pdd/meta/cli_theme_python.json index 0adcc03a55..bb7b0cc213 100644 --- a/.pdd/meta/cli_theme_python.json +++ b/.pdd/meta/cli_theme_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.278.dev0", - "timestamp": "2026-06-19T04:14:17.493767+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.323046+00:00", "command": "fix", "prompt_hash": "92ea1f8c1b4039771ee67668a380f44dffc6d976751dd1ec78a498f2c55defb5", "code_hash": "00d434d8798de28ba50dfc195655f57e9ac671cf178c6d77a473dd18e5cd1b06", diff --git a/.pdd/meta/cmd_test_main_python.json b/.pdd/meta/cmd_test_main_python.json new file mode 100644 index 0000000000..e7f37fc613 --- /dev/null +++ b/.pdd/meta/cmd_test_main_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.325051+00:00", + "command": "fix", + "prompt_hash": "fd8c3c5aabaf7330982ece58d638099c28e7ae5bb97f2d868ee528190ca71b8d", + "code_hash": "cc809a1c54c8f4aa2ac4dd9e391d89df4b4e1be2dacc42f0a71306b4a666cf3d", + "example_hash": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", + "test_hash": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643", + "test_files": { + "test_cmd_test_main.py": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/cloud_function_call.py": "62ac7724ce2e3eddbba2b743bd7aa5790dbed34eae01e77e0252c4cc6358c95e", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/generate_test_example.py": "f73533a9cf63f2e2f4818ee923a8500e612d155e230017dbdb35aec945e41998", + "context/get_jwt_token_example.py": "76a87c8257cb1f4cfdc2edff6225c752432afb3a5e352fcb016d08d8eae16e01", + "context/increase_tests_example.py": "f53be429e9a9e6a523c770ed6d0d4498e2201b22d5a8e4ef28ac64e8ff172c91" + } +} \ No newline at end of file diff --git a/.pdd/meta/code_generator_main_python.json b/.pdd/meta/code_generator_main_python.json index 0f74e423fd..b58274d6a2 100644 --- a/.pdd/meta/code_generator_main_python.json +++ b/.pdd/meta/code_generator_main_python.json @@ -1,29 +1,29 @@ { - "pdd_version": "0.0.268", - "timestamp": "2026-06-09T23:30:32.073262+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.329127+00:00", "command": "example", - "prompt_hash": "9c646810b3e55fa6ba5c0bb1d8210e459446ffa6826c565d7012ea6bd55fb6d5", - "code_hash": "1293a25723fdcb7870711b4759248fe4681d5107cf2106feff61df57cb56ee96", - "example_hash": "25bb0d4b5fe4f31d0d4d3795d24e8e9bb2cd346c74e4fc916d0a9ba8590141be", - "test_hash": "3cc05a05384f982254fdb38d8a156fc7507a1dfec200fc91705d01fbbfad134d", + "prompt_hash": "b0e5511b3cfab37280bfa33b4def679b78664af37da564d77d56a324e0466670", + "code_hash": "e83cc9bd8890d032fcf63001b83feb766d632ab08d00e20110e489e0386962b4", + "example_hash": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", + "test_hash": "5770dba6d2f38bfb7d8051e866bf622b43401b073ac8d97202fe25b4e805d231", "test_files": { - "test_code_generator_main.py": "3cc05a05384f982254fdb38d8a156fc7507a1dfec200fc91705d01fbbfad134d" + "test_code_generator_main.py": "5770dba6d2f38bfb7d8051e866bf622b43401b073ac8d97202fe25b4e805d231" }, "include_deps": { "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", "context/_keyring_timeout_example.py": "41f83d5ef117caba86b788f69b519f7e88f3d7dc2a641a017d74a7cee9be6ed1", "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", "context/api_key_scanner_example.py": "4b9f880a30445f25edffc394857ae0c218097726c41ab996a03fcbc4350b5482", - "context/architecture_sync_example.py": "6e1f65de35fcf1dbd0def81710da6f378495b37187eb01cd01ef43f662d9f1ba", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", "context/auto_include_example.py": "0c278ed716298149777bc7082827eb8aa6d80dac264c66b6cded6871232f2df7", "pdd/code_generator.py": "33235364b431edbb0fb1c4d8eb03fa21a3b776e07ea585530c19212da20c486d", - "pdd/code_generator_main.py": "1293a25723fdcb7870711b4759248fe4681d5107cf2106feff61df57cb56ee96", - "pdd/construct_paths.py": "832d478849bfe83c12d4a473c270902d0af0be577ae3276b07ef8a48c148d35f", + "pdd/code_generator_main.py": "e83cc9bd8890d032fcf63001b83feb766d632ab08d00e20110e489e0386962b4", + "pdd/construct_paths.py": "7b42a002e4ecc27be4d517cbc07f1fc9425e795d4918714f382d2ed5ddd00eab", "pdd/core/cloud.py": "0487c0b989996af144df3af1c818a6eeafe52fd209710e5a54eb43990c89ae97", - "pdd/incremental_code_generator.py": "266a4bed6ea41519a1b1c3c33057cb33cffecd2a3075ee0c2f790798bfff4834", - "pdd/preprocess.py": "a6c86dd348d0028a0638114338013e4633fb66fa51f756bc30458f4dce833703", + "pdd/incremental_code_generator.py": "8dd5dd7f3016b8fae86056484fdc49b824405cdcd6911e8b8657d3e043b3b06d", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56", "pdd/python_env_detector.py": "cbe4044a83cd88a683f36d6ecfca245fef6a03ea2abc7f5c407636fccc051f35", - "prompts/context_snapshot_python.prompt": "d8e129b55b27814d16e7566f07dfdaae0cc6950352f351fd78cfeeab125a7cbf" + "prompts/context_snapshot_python.prompt": "05f46fa9adba7ed3c9c6088d150ad821c723e9d0a3efed9db2fe8a461386da9d" } } \ No newline at end of file diff --git a/.pdd/meta/code_generator_python.json b/.pdd/meta/code_generator_python.json new file mode 100644 index 0000000000..1ca90c5ced --- /dev/null +++ b/.pdd/meta/code_generator_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.330448+00:00", + "command": "fix", + "prompt_hash": "2db9dd103925fef2b56138d3fa0056d86d30d1026e60ea17477d892d6df1357e", + "code_hash": "33235364b431edbb0fb1c4d8eb03fa21a3b776e07ea585530c19212da20c486d", + "example_hash": "4e66ed9866b05a2de791376d4881ae5d1d52ac4a6ea99176dce8febdf9a14355", + "test_hash": "48919cac185306dfdcb2d37f86596c9858b1f6515a16b36dadd1491448f34566", + "test_files": { + "test_code_generator.py": "48919cac185306dfdcb2d37f86596c9858b1f6515a16b36dadd1491448f34566", + "test_code_generator_main.py": "5770dba6d2f38bfb7d8051e866bf622b43401b073ac8d97202fe25b4e805d231" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/codex_subscription_python.json b/.pdd/meta/codex_subscription_python.json new file mode 100644 index 0000000000..b6df612848 --- /dev/null +++ b/.pdd/meta/codex_subscription_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.330840+00:00", + "command": "fix", + "prompt_hash": "17eedbc09a256171e39540fdd62097d30a4d66fba0fb20843b994315e2d5fc3c", + "code_hash": "4a3ff334aa58b5f8e004f2eff9a67a041ed0a4d374a6646090239d8b6411df1a", + "example_hash": null, + "test_hash": "e26c73fc92e9cba43f3e225860f20e593f398118fe17db33c03a10bd9b3ff849", + "test_files": { + "test_codex_subscription.py": "e26c73fc92e9cba43f3e225860f20e593f398118fe17db33c03a10bd9b3ff849" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/commands_analysis_python.json b/.pdd/meta/commands_analysis_python.json new file mode 100644 index 0000000000..38b0e36622 --- /dev/null +++ b/.pdd/meta/commands_analysis_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.332634+00:00", + "command": "fix", + "prompt_hash": "f618f0ee1b3dfb720406f22d8c6dacf83a0e99942a0e7432a6d3d29526f0c4b7", + "code_hash": "a553780c2267d05af75ea447ea01e94519ab7b5a27e940abec6183797e7fb1ba", + "example_hash": "01ff82910c50ec8f8cfd22f8e3b7c011f286a4b9f90e7dd5b2eb685c1f339e56", + "test_hash": "0e747c6b4b27cad8f2b651663bc4ae01dacdb5f01558c0996ec39a6af7d19fa4", + "test_files": { + "test_analysis.py": "0e747c6b4b27cad8f2b651663bc4ae01dacdb5f01558c0996ec39a6af7d19fa4" + }, + "include_deps": { + "context/agentic_bug_example.py": "96e35df4e8425a9173ff6a30281892c2bd8b81361cff72b732e488172ddf52f5", + "context/bug_main_example.py": "662ecde39d05a5345533c4ae74c6b1031f016916ec2ff4764d34a26f7ec26172", + "context/conflicts_main_example.py": "36e9f73fd888af26dc73f35ee765715e99e4325881bc0ffdc5d70106eda7e239", + "context/crash_main_example.py": "5c9b909107f74f773ccf7013d556a5812643d2a3b086e79fe07da7ea7877458c", + "context/detect_change_main_example.py": "ddc494709d127398004f53de58bede388692b2839a97b26668c55575369d9edd", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/trace_main_example.py": "c1f43ebf55c05af801640f5f8331ee7a674aef9e3f383b0e5ffee7abc7246fe1", + "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_auth_python.json b/.pdd/meta/commands_auth_python.json new file mode 100644 index 0000000000..63dad4b12f --- /dev/null +++ b/.pdd/meta/commands_auth_python.json @@ -0,0 +1,20 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.334010+00:00", + "command": "fix", + "prompt_hash": "9c6188da46f58639009a26f6848c90e714785bb0b89d8bb86ed44454209318a9", + "code_hash": "c33a045aa16c202eacc6c195bdef5d88c24ac7df2e36a9d7f3172de7963b768d", + "example_hash": "d1e77e2ab5a5b6f3c400a8a68a73bb633f6d45e39dd4a90306dcc18c729d9000", + "test_hash": "258c7340e7bcf624d67f5b5f25907cf55e328215c7f4aae9edd156d5f4066af7", + "test_files": { + "test_auth.py": "258c7340e7bcf624d67f5b5f25907cf55e328215c7f4aae9edd156d5f4066af7" + }, + "include_deps": { + "context/_keyring_timeout_example.py": "41f83d5ef117caba86b788f69b519f7e88f3d7dc2a641a017d74a7cee9be6ed1", + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/commands/__init___example.py": "cc6e0de7d94b1dddda35d9c8ecb800710263d928191f1d4cb2400bae36c31cb4", + "context/core/cloud_example.py": "8a14ae9e69dbccfbbfffd9bde1ea11192334a10aaf9d5b5e6dba5ac23ba0dd90", + "context/get_jwt_token_example.py": "76a87c8257cb1f4cfdc2edff6225c752432afb3a5e352fcb016d08d8eae16e01", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_checkup_python.json b/.pdd/meta/commands_checkup_python.json index ad99414b05..896d30ae85 100644 --- a/.pdd/meta/commands_checkup_python.json +++ b/.pdd/meta/commands_checkup_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.288.dev0", - "timestamp": "2026-06-26T22:58:40.738135+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.335452+00:00", "command": "test", - "prompt_hash": "f26cc513b81c467f58c2bbf0b79d1186904a48d7d801faa69302ac59eba64f39", + "prompt_hash": "d42ff466ad8a19df7c2101a92e4b38737707e87ef7b59a64e77133a2c848a0b4", "code_hash": "0b7936aabeb40dd4eb0bde84d3693b8df3b5f423b3514b740b4fa4140a64ee6e", "example_hash": "847008502198ff360190831172d5d6cc6de6e5e76d3782d2b53823297a5b1349", "test_hash": "790c9e6532de75e9b2b4b1912a61c4fdcea229568cd40572245f06a1985be628", @@ -15,8 +15,8 @@ "include_deps": { "context/agentic_checkup_orchestrator_example.py": "295a9ae294e22224d3c447f13c462854bfe4e526cebc89bcbba417ea514c7ef2", "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", - "context/agentic_sync_example.py": "9bcc2f199a1463e8c424d8210ea6d5f34ad6fb5fcb1022aa879a9ecba0f8d5d6", + "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } -} +} \ No newline at end of file diff --git a/.pdd/meta/commands_checkup_simplify_python.json b/.pdd/meta/commands_checkup_simplify_python.json new file mode 100644 index 0000000000..6f91aa0354 --- /dev/null +++ b/.pdd/meta/commands_checkup_simplify_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.336126+00:00", + "command": "fix", + "prompt_hash": "879ba667d716fcf666ee1df507348749953d0dfba4e099fa0a9bac016945e101", + "code_hash": "6ec8b1694b0ec8c9955261fff159b1a86397d54f24a0f95ea5243ac9cbd6df7f", + "example_hash": null, + "test_hash": "2a80956f21f2873e3eb48a113c6f756019db9e9b74b8a5e91e9052648caf8707", + "test_files": { + "test_checkup_simplify.py": "2a80956f21f2873e3eb48a113c6f756019db9e9b74b8a5e91e9052648caf8707" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_connect_python.json b/.pdd/meta/commands_connect_python.json new file mode 100644 index 0000000000..f21808451c --- /dev/null +++ b/.pdd/meta/commands_connect_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.337357+00:00", + "command": "fix", + "prompt_hash": "a881214405113719a1009a1bd4ec2c340fbce3fa764c7d50a5e6965a7b5ef3b2", + "code_hash": "f3a2c8d66a2f2555188a61a4828a5114bf1b99e6c2ebf19f84aef2b7da39cc5e", + "example_hash": "d2bcda4ae1e9de22d1b657c28045a0b122dc1ef22a77e4d670f41229779a6083", + "test_hash": "fad9177f084c4ce574ce11a468f55206bcd45dc7602601775f800bc39272252e", + "test_files": { + "test_connect.py": "fad9177f084c4ce574ce11a468f55206bcd45dc7602601775f800bc39272252e" + }, + "include_deps": { + "context/commands/__init___example.py": "cc6e0de7d94b1dddda35d9c8ecb800710263d928191f1d4cb2400bae36c31cb4", + "context/commands/misc_example.py": "7d7985d21dd7b962257856cb92d13e26c016bc09ce14aaac4c68baaead97dc4b", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/remote_session_example.py": "ebcf3626cc73386164ac48e804e2e7973cb9783892ac88cda49779cf158389c5", + "context/server/app_example.py": "554bb0307f2f7a0dc79ef86f8a4fd42e5017225d0c56379ad99d2939f3c1087a" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_context_python.json b/.pdd/meta/commands_context_python.json new file mode 100644 index 0000000000..c75fd15d12 --- /dev/null +++ b/.pdd/meta/commands_context_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.338066+00:00", + "command": "fix", + "prompt_hash": "e7351a988d749a910cd9dca718bb35d3a037a4a8fc75dd4211fb0e72f9b953cd", + "code_hash": "3b67e44225298a9a76412cde3b8a933dad9e5a74be731453edf2e527bec5ee63", + "example_hash": null, + "test_hash": "9f907c4708d249f15104b0352694359b0e901ff0c8de5bfd32dfa658a62d90d6", + "test_files": { + "test_context.py": "9f907c4708d249f15104b0352694359b0e901ff0c8de5bfd32dfa658a62d90d6" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "prompts/commands/replay_python.prompt": "58cdc1775f5b2777fa766261fd6bb46385c1bd079630046fe4b67abee0c88778" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_contracts_python.json b/.pdd/meta/commands_contracts_python.json new file mode 100644 index 0000000000..9fe4b58a73 --- /dev/null +++ b/.pdd/meta/commands_contracts_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.338427+00:00", + "command": "fix", + "prompt_hash": "ad58fc1a29f77c72d231a233db025de60a25c6509b030d198cdd77bed1e7d8cb", + "code_hash": "cf070bb6670f4051aacf864306095707c581c6a48e57876d4d41d546fec5981c", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_firecrawl_python.json b/.pdd/meta/commands_firecrawl_python.json new file mode 100644 index 0000000000..190af2a51e --- /dev/null +++ b/.pdd/meta/commands_firecrawl_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.338790+00:00", + "command": "fix", + "prompt_hash": "e94170a1ab45cc700c6420a694f00624b4372d76a11746b6476162958e9de03a", + "code_hash": "ef4b2875252e86550cbe6c87e07a3662edff352f87c3affdbf0393146833be7f", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_fix_python.json b/.pdd/meta/commands_fix_python.json new file mode 100644 index 0000000000..4390dfabb3 --- /dev/null +++ b/.pdd/meta/commands_fix_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.339712+00:00", + "command": "fix", + "prompt_hash": "71d34c70ff508a726367285baaf296c9032b316bf81c5cbc97d6b900553d718a", + "code_hash": "52a8eaa4c37566690f374fe5f596cf1d63762c8e68c1133985042d8571fd6543", + "example_hash": "4b2db39fec015e750d59894877e7dc630152aff56fe262dee275f03ba2c6f97d", + "test_hash": "837ea1b2e8d5c1019893b1461f97a00511a3d018e19b4faf443e91d4e9589eda", + "test_files": { + "test_fix.py": "837ea1b2e8d5c1019893b1461f97a00511a3d018e19b4faf443e91d4e9589eda" + }, + "include_deps": { + "context/agentic_e2e_fix_example.py": "79fd30a0fa6d8a5b9e23b34f7328ba3f95089a0ebb83e8244dae79ea68cff33a", + "context/fix_main_example.py": "29f88d8bfcc2256ebebe6efcb611f9487eb5ca6d8781286a6dd98689f92bca7a", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_gate_python.json b/.pdd/meta/commands_gate_python.json new file mode 100644 index 0000000000..21fced1039 --- /dev/null +++ b/.pdd/meta/commands_gate_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.340071+00:00", + "command": "fix", + "prompt_hash": "55c2e3207298e63d0362345861747fe6711b18fd5f9f4acb9d6d73c821840542", + "code_hash": "c75e65038098b8cbf57526c341028047c24f2813fcea2b3daeffe76bd1b57832", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_generate_python.json b/.pdd/meta/commands_generate_python.json new file mode 100644 index 0000000000..35bdd7dbb5 --- /dev/null +++ b/.pdd/meta/commands_generate_python.json @@ -0,0 +1,24 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.341906+00:00", + "command": "fix", + "prompt_hash": "8192f9b9659b22fbfab38d99fa9d7d7316b582c0a365e28405e0d09c5d2c872c", + "code_hash": "fc493964a405a7bc8444b131d27f98ca6af7cd08d569b99f09eb865a1eeae0b8", + "example_hash": "ecfaafca740d69b46d569368cb5a289410cf6fde5ef45c880bde396c797052c2", + "test_hash": "48a327fef36aee1f20360177bf65e862b57587d7977acc1d862352df8391eb97", + "test_files": { + "test_generate.py": "48a327fef36aee1f20360177bf65e862b57587d7977acc1d862352df8391eb97" + }, + "include_deps": { + "context/agentic_architecture_example.py": "f82ea3f16297c0cd0f7993549054bc9213953ebe03144aa5abc7bd74ba707e13", + "context/agentic_test_example.py": "1d8b490a2b0ff53a8b786c6c95faeecc4efd0becf837b35273508bae19fac3ab", + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", + "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", + "context/context_generator_main_example.py": "77c3de786f31392540ec609d4b3942e98e996ae14c4014f5018cf2b05a560df4", + "context/operation_log_example.py": "2660def7012d9b79bad3db33cf399ac603cc1c35dff0b064cbdd2638a013de1d", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6", + "pdd/user_story_tests.py": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_maintenance_python.json b/.pdd/meta/commands_maintenance_python.json new file mode 100644 index 0000000000..a8be945a13 --- /dev/null +++ b/.pdd/meta/commands_maintenance_python.json @@ -0,0 +1,23 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.344275+00:00", + "command": "fix", + "prompt_hash": "23aabe03f05d6759579e5a82ee07948b85f6c1db03e44ed417f577ac447cc9c6", + "code_hash": "2e6fc948c35d4ec0e3b9d08b1d3f53046ae9d3b80f9787cf7e0d29edc4ced5c9", + "example_hash": "89252d2bb50c54846397d3ec319aae9ce69434d2af7a6d746dd7d85a317216e6", + "test_hash": "87c5eb09a222437ac1dcccf4085993b870ea71af86f0077fff33292f17c37d00", + "test_files": { + "test_maintenance.py": "87c5eb09a222437ac1dcccf4085993b870ea71af86f0077fff33292f17c37d00" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", + "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", + "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/sync_main_example.py": "9a7961a4044a54c46ce6c43c8adbbb83da46f233d9c6a9eaa28302440c0052c0", + "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_misc_python.json b/.pdd/meta/commands_misc_python.json new file mode 100644 index 0000000000..32d66d27cc --- /dev/null +++ b/.pdd/meta/commands_misc_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.345532+00:00", + "command": "fix", + "prompt_hash": "a2c00fc2b14606cb984ad67d1dc074edbe9899f6f07adc2cf99b6b0c2c31a57f", + "code_hash": "e49fff5cb806fc88e2ba5e54f445f2b2f855d6902946319c47a264ab6f13885c", + "example_hash": "7d7985d21dd7b962257856cb92d13e26c016bc09ce14aaac4c68baaead97dc4b", + "test_hash": null, + "test_files": {}, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/preprocess_main_example.py": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_modify_python.json b/.pdd/meta/commands_modify_python.json index 554d70abc8..8ed83b0ff8 100644 --- a/.pdd/meta/commands_modify_python.json +++ b/.pdd/meta/commands_modify_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.233", - "timestamp": "2026-05-26T00:00:00.000000+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.347761+00:00", "command": "fix", - "prompt_hash": "fe1b5bb35af67e03327d83b877d8eff14be1ee1ab5379bf3190ddaf2d49001cc", - "code_hash": "35c29832636deb8dd6be2f637b3ccdc6e965e044b6554fb1befca967790b0ca1", + "prompt_hash": "2f9a78de992e04c361ee0559f689b4c4b1f5d46f84ccf773ba208ebc0ea80a5b", + "code_hash": "666d20da91b1037b24aa9a5c9f10684417ac31ad9c5c765c7b59d50916db7a99", "example_hash": "84edd899e3202fe13dc2e9437505a85552ec870b325e5628727d7202371d8134", - "test_hash": "8915daf33703cfcd6e2561795faf0b400534c24a49d2ef5e971edd51efde3106", + "test_hash": "86242f8ba65ee0bd4c5224b7c39f243c851a66a8812d4747d543e77fda043707", "test_files": { - "tests/commands/test_modify.py": "8915daf33703cfcd6e2561795faf0b400534c24a49d2ef5e971edd51efde3106" + "test_modify.py": "86242f8ba65ee0bd4c5224b7c39f243c851a66a8812d4747d543e77fda043707" }, "include_deps": { "context/agentic_change_example.py": "a8308b2af708c804d626a4a96012c5a67f5bc6469e33857cafc07627213828d7", @@ -19,6 +19,6 @@ "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/split_main_example.py": "ced192fcbfbfda15b35bd2dad5bbf4b4888acb091084cf58326832d224a77661", "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6", - "context/update_main_example.py": "b318834c648f25e6141d81f3ecac1d9da592a6bb4740500983f2b07b8a10d902" + "context/update_main_example.py": "9fe01fd19196c2604c91d101e49db849e0e1c9fabafeb2ad831a9c91b2f26416" } -} +} \ No newline at end of file diff --git a/.pdd/meta/commands_prompt_python.json b/.pdd/meta/commands_prompt_python.json index 2b322ebb99..1764d0c43b 100644 --- a/.pdd/meta/commands_prompt_python.json +++ b/.pdd/meta/commands_prompt_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.251.dev112", - "timestamp": "2026-05-27T04:45:33.151707+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.348411+00:00", "command": "test", "prompt_hash": "49253a7519e0deac37df0994c88519e0e4868e2c5420afd0fcf4eb89426e6583", "code_hash": "8c1e3e7d8dfaab47ee8c309c5fa7d3662b183807f5116dfd8e3d03aeba2adc6c", diff --git a/.pdd/meta/commands_replay_python.json b/.pdd/meta/commands_replay_python.json new file mode 100644 index 0000000000..cae8fdcc16 --- /dev/null +++ b/.pdd/meta/commands_replay_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.349307+00:00", + "command": "fix", + "prompt_hash": "ac7765224d914a62041e86ed93be1e13fcab04bc1530083032596057e96f07ed", + "code_hash": "6bb573b739993026c3aea2b3e47decd12420c33eb9932d7e7098058e600ff5b3", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "prompts/context_snapshot_python.prompt": "05f46fa9adba7ed3c9c6088d150ad821c723e9d0a3efed9db2fe8a461386da9d" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_report_python.json b/.pdd/meta/commands_report_python.json new file mode 100644 index 0000000000..9b3aa00588 --- /dev/null +++ b/.pdd/meta/commands_report_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.350107+00:00", + "command": "fix", + "prompt_hash": "388398722a80945d1338eee36a96481e02911ec6d5e63e15a546a7d1dbe047b3", + "code_hash": "c07ff974784d7f8f08b464e4326f6e22bb1250945411531dc3860cd7609f5c35", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/core/dump_example.py": "0416a935ac490b958ceedfc6e68c7fbd7e383966374ba13ccf7ebfeaf8ad0803", + "context/core/errors_example.py": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_sessions_python.json b/.pdd/meta/commands_sessions_python.json new file mode 100644 index 0000000000..56937427c7 --- /dev/null +++ b/.pdd/meta/commands_sessions_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.350965+00:00", + "command": "fix", + "prompt_hash": "cdfcedf57ee76527c398fbda65c5ee8050c523b3dcafb7c8ec8d0d65ea452422", + "code_hash": "8b05a311e2ad2ef499eb6c97b4f68308f659f87976770181eb0b946a41012266", + "example_hash": "d235c7a2fad154663ce3016baa1babd45a1b5fa5041ba130024dbe88ab791a28", + "test_hash": "38af3c6838c75f99f3a8082116b8a2f0e771ba915be87fcf9bb377b5f57e8b76", + "test_files": { + "test_sessions.py": "38af3c6838c75f99f3a8082116b8a2f0e771ba915be87fcf9bb377b5f57e8b76" + }, + "include_deps": { + "context/core/cloud_example.py": "8a14ae9e69dbccfbbfffd9bde1ea11192334a10aaf9d5b5e6dba5ac23ba0dd90", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/remote_session_example.py": "ebcf3626cc73386164ac48e804e2e7973cb9783892ac88cda49779cf158389c5" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_story_python.json b/.pdd/meta/commands_story_python.json new file mode 100644 index 0000000000..323954bcc4 --- /dev/null +++ b/.pdd/meta/commands_story_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.351702+00:00", + "command": "fix", + "prompt_hash": "8504142f3ab73f5beb85bc0f7bf5c5b92828bf54d1006e2c2cc6aa366a1cad7b", + "code_hash": "a72c43090f69470d83fa4ec5836cd1528c9f8c8d98f063468833afb61030e736", + "example_hash": null, + "test_hash": "f727eec05860b2f06cab71af9b9b52f2e1a070b00e96840090b577e46f7e1779", + "test_files": { + "test_story.py": "f727eec05860b2f06cab71af9b9b52f2e1a070b00e96840090b577e46f7e1779" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/user_story_tests.py": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_templates_python.json b/.pdd/meta/commands_templates_python.json new file mode 100644 index 0000000000..2bd63dd44b --- /dev/null +++ b/.pdd/meta/commands_templates_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.352705+00:00", + "command": "fix", + "prompt_hash": "f7452b0f2c022c68f5a2e522b6d2fe535cb081161c0515ba3593a9b1ceeb7e42", + "code_hash": "6cb72959c02bcb9df6c2661ed339d61a782f4466980c0f899371af2113818dd0", + "example_hash": "017d7a9cbdec60dd67cee662f3b21a68638137cd086fb335ef92889e1d91b09a", + "test_hash": null, + "test_files": {}, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_utility_python.json b/.pdd/meta/commands_utility_python.json new file mode 100644 index 0000000000..1430aaa8c8 --- /dev/null +++ b/.pdd/meta/commands_utility_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.354230+00:00", + "command": "fix", + "prompt_hash": "3c02cfee56c2b08e75d0fedaba42a7f4246bf9d2a192f79a486da112c123d29c", + "code_hash": "9d0f70da4a91baf636335b69168fff3806b48d8fa6bc6bf0ca8c910bf1f11559", + "example_hash": "fb7389c0ec837b8b6ee481e2eda04800f565fe247643f5bb9922dd1dfdab984a", + "test_hash": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31", + "test_files": { + "test_utility.py": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/fix_verification_main_example.py": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", + "context/install_completion_example.py": "999be17c0ce476845d7048a1a909ad425e60c298dbc7c74f51b596ef134a8aec", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6" + } +} \ No newline at end of file diff --git a/.pdd/meta/commands_which_python.json b/.pdd/meta/commands_which_python.json new file mode 100644 index 0000000000..a99965cd8b --- /dev/null +++ b/.pdd/meta/commands_which_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.355005+00:00", + "command": "fix", + "prompt_hash": "2f3eac13978f6cbf66396d352071f00a3a670e81a6ca48206fa784aff9ae1882", + "code_hash": "c36548d914d06d2c2b56c55b607249eaadb7c162cf1b1284d0377c79790214fa", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", + "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/comment_line_python.json b/.pdd/meta/comment_line_python.json new file mode 100644 index 0000000000..686e0feca5 --- /dev/null +++ b/.pdd/meta/comment_line_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.355358+00:00", + "command": "fix", + "prompt_hash": "f5012401ed39f35053deac030ea7bf5444c31b88a7d1380807895ecea0e0e6c4", + "code_hash": "b17da17f86c6d5f20b8bfaef23d324930099d888ad80a916ee73a2c3c69028f6", + "example_hash": "debc424d539b65aef1267888bb2eb77cf4de16745407bb5df5a18b8e2f231095", + "test_hash": "1c7f412de99137ecf6240c7d03eb7453334864768ef60360704890b46ee0bd83", + "test_files": { + "test_comment_line.py": "1c7f412de99137ecf6240c7d03eb7453334864768ef60360704890b46ee0bd83" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/compressed_sync_context_python.json b/.pdd/meta/compressed_sync_context_python.json new file mode 100644 index 0000000000..b90591131e --- /dev/null +++ b/.pdd/meta/compressed_sync_context_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.356507+00:00", + "command": "fix", + "prompt_hash": "c167d3127c74eab08bfd5a5293c8264e0582e777722fc47f0608b78bec5707ee", + "code_hash": "661fde0fcc42ce39c1004e47a774a8fd799b789065519cb5688949c35fed4859", + "example_hash": null, + "test_hash": "5fd1feba54991f20e5e95264a7bcc9055cdb541f8c7df5a2f7d90b22b936af2f", + "test_files": { + "test_compressed_sync_context.py": "5fd1feba54991f20e5e95264a7bcc9055cdb541f8c7df5a2f7d90b22b936af2f" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/context_snapshot.py": "6aa1ea0d41f73c40b02b72603f6193d4b6e51fdefb57d62f501311365a9ab1b8", + "pdd/contract_ir.py": "0d3392ec8990ac0ff6ddb4a00fee3c6719395f046a59a263ade7d8676e3648e9", + "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", + "pdd/test_context_packer.py": "27c7d14747d38df8edf24c8ef2ce1b7ca21d8f2eea38aec02ba06042ee144c0b" + } +} \ No newline at end of file diff --git a/.pdd/meta/config_resolution_python.json b/.pdd/meta/config_resolution_python.json new file mode 100644 index 0000000000..ed16b0cafd --- /dev/null +++ b/.pdd/meta/config_resolution_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.357030+00:00", + "command": "fix", + "prompt_hash": "f623b13d873302a7d13d94fe5d8556aa818f138dca71b4b8633dbce77bbbe030", + "code_hash": "d50eb62241f36eed780d793a4631444f6f62e2551cff831e5c133f5dddc6a291", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/__init__.py": "52c9a7d1a0608830d7f112b533c0bc2990435813d6d7c8dac921530e862bf5dd" + } +} \ No newline at end of file diff --git a/.pdd/meta/conflicts_in_prompts_python.json b/.pdd/meta/conflicts_in_prompts_python.json new file mode 100644 index 0000000000..1d3bf9fc8f --- /dev/null +++ b/.pdd/meta/conflicts_in_prompts_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.357741+00:00", + "command": "fix", + "prompt_hash": "06501ee2b4c3a052873db04a0f3c8b629de39d655f665459591961d1e613fabc", + "code_hash": "c0bd91a9575d399f8d95a428c1f96c227c4a85985ba3efc36e89c3b6d2e44c01", + "example_hash": "d286f38ca6e43216d62197230f6c53ec665734db782d965e5448f8e9f8bbdfb2", + "test_hash": "21832d31b23e3e2898a4d64828d515f6f3196c8a48832570af4d7717a0e631c7", + "test_files": { + "test_conflicts_in_prompts.py": "21832d31b23e3e2898a4d64828d515f6f3196c8a48832570af4d7717a0e631c7" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f" + } +} \ No newline at end of file diff --git a/.pdd/meta/conflicts_main_python.json b/.pdd/meta/conflicts_main_python.json new file mode 100644 index 0000000000..8e666717b3 --- /dev/null +++ b/.pdd/meta/conflicts_main_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.358584+00:00", + "command": "fix", + "prompt_hash": "7a2bb8b334031ae46ded9dd01e1c0fa4cf4c68fc863dd33a347d36d0f95ea662", + "code_hash": "63eb4e64da42e51be42ce4d691e6f4928753f99efd017359944a81ad114fc1be", + "example_hash": "36e9f73fd888af26dc73f35ee765715e99e4325881bc0ffdc5d70106eda7e239", + "test_hash": "aad1db3e48e41d608905390ad1cfa8bd109ffa1b0d65cb75d8863ac4afe5751d", + "test_files": { + "test_conflicts_main.py": "aad1db3e48e41d608905390ad1cfa8bd109ffa1b0d65cb75d8863ac4afe5751d" + }, + "include_deps": { + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/conflicts_in_prompts_example.py": "d286f38ca6e43216d62197230f6c53ec665734db782d965e5448f8e9f8bbdfb2", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/construct_paths_python.json b/.pdd/meta/construct_paths_python.json index 950822c8d3..74ade20208 100644 --- a/.pdd/meta/construct_paths_python.json +++ b/.pdd/meta/construct_paths_python.json @@ -1,16 +1,16 @@ { - "pdd_version": "0.0.278.dev0", - "timestamp": "2026-06-19T04:14:17.583096+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.360478+00:00", "command": "fix", - "prompt_hash": "2b7c13628eda07779cc96080af940fb135118e626453a902f370b1864484d447", - "code_hash": "556b154328d8400f46209c9c8af61e7162675becfb49a4bf55d42f045972243c", + "prompt_hash": "aa2c66e90540778ffe0df4ba14faeb39de2ea1b4e225ed21d88df36f92243607", + "code_hash": "7b42a002e4ecc27be4d517cbc07f1fc9425e795d4918714f382d2ed5ddd00eab", "example_hash": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", - "test_hash": "a6a100f304748466b50be8cade7bfbad2dec3b81c9c285f9bf2213072a5ea5a1", + "test_hash": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418", "test_files": { - "test_construct_paths.py": "a6a100f304748466b50be8cade7bfbad2dec3b81c9c285f9bf2213072a5ea5a1" + "test_construct_paths.py": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418" }, "include_deps": { - "README.md": "80504ec987045c156641c781764ebbd33af20da3e8854307158fe1110fe1845b", + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", "context/generate_output_paths_example.py": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", diff --git a/.pdd/meta/content_selector_python.json b/.pdd/meta/content_selector_python.json new file mode 100644 index 0000000000..0be6871b9b --- /dev/null +++ b/.pdd/meta/content_selector_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.361320+00:00", + "command": "fix", + "prompt_hash": "584ea795707777378846cdcc413bbf1754ee3638d141878a4095c41a791b583b", + "code_hash": "c18d5f9ce0903169445ee17d2e408b88ad91a931e710e783f7c9c7cc3f2ec4af", + "example_hash": "1b71d5d614f81c6543cc3a437ed8fcaa810372b06dc9bf23bde3cd09d9d715e6", + "test_hash": "acfbcbea92e5b943890af0983083d9dca84c7b4c6dd8d0980ec303815f45dbc6", + "test_files": { + "test_content_selector.py": "acfbcbea92e5b943890af0983083d9dca84c7b4c6dd8d0980ec303815f45dbc6" + }, + "include_deps": { + "context/core/errors_example.py": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/pytest_slicer.py": "c02a5488fe6f7248ed387636d5824cb2f1876544d3991e43ef253648a36e49a2" + } +} \ No newline at end of file diff --git a/.pdd/meta/context_audit_python.json b/.pdd/meta/context_audit_python.json index 93bade2994..39575fdc37 100644 --- a/.pdd/meta/context_audit_python.json +++ b/.pdd/meta/context_audit_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.270.dev0", - "timestamp": "2026-06-10T23:02:30.507619+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.362163+00:00", "command": "fix", "prompt_hash": "8ddab8adfedeb2b501ae5df3b1989d446c13a72f64ea55668f62b75c605eff6d", "code_hash": "e9a2c33294a9045ed7eb93c4a4c53ae27added9e2b408619d7c5204386893b45", @@ -12,4 +12,4 @@ "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } -} +} \ No newline at end of file diff --git a/.pdd/meta/context_generator_main_python.json b/.pdd/meta/context_generator_main_python.json new file mode 100644 index 0000000000..15e91cbcae --- /dev/null +++ b/.pdd/meta/context_generator_main_python.json @@ -0,0 +1,23 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.364339+00:00", + "command": "fix", + "prompt_hash": "25d5bc7ab8ea0cc23287232060cb5d9d13b5523dcd5c2facaa84ac60d7d8fee1", + "code_hash": "ea5831e4bafe49e056cc2d7e18be7b632f8de5752004bf08e66ebc4c82688c14", + "example_hash": "77c3de786f31392540ec609d4b3942e98e996ae14c4014f5018cf2b05a560df4", + "test_hash": "96a066f4b0dfdc29fb7f28b51edfb0621e61de3167ddd9972fbc41eda92f4d9c", + "test_files": { + "test_context_generator_main.py": "96a066f4b0dfdc29fb7f28b51edfb0621e61de3167ddd9972fbc41eda92f4d9c" + }, + "include_deps": { + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/change/15/README.md": "1fc1b1dc45e3f0178c7dc607c7b2ac723fd990d2277e384defd8956221183abe", + "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74", + "context/change/19/context_generator.py": "046c50404d58d06586c6acb481acbd2e20042de7155b5f7eaffab5ebebceda0a", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/context_generator_example.py": "277b54ee71ffc836d9db9ad4d4fc0b3fee365ce6f5691222acad11b58461923b", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/context_generator_python.json b/.pdd/meta/context_generator_python.json new file mode 100644 index 0000000000..3406d6ac8f --- /dev/null +++ b/.pdd/meta/context_generator_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.365998+00:00", + "command": "fix", + "prompt_hash": "3417f94071a8113de24dbc9a3bbb393e85bd04a1b6fedd555ef0a1f39e57f164", + "code_hash": "f972e2e2ce7444b7d3d186ab4540b8cad4f66dd0d97d37df00c58f32a9e3e369", + "example_hash": "277b54ee71ffc836d9db9ad4d4fc0b3fee365ce6f5691222acad11b58461923b", + "test_hash": "a9f7878a97090fd2021fd0f39213f0d1fb8fc8f3207df7e985e2fa4caa91ac76", + "test_files": { + "test_context_generator.py": "a9f7878a97090fd2021fd0f39213f0d1fb8fc8f3207df7e985e2fa4caa91ac76", + "test_context_generator_main.py": "96a066f4b0dfdc29fb7f28b51edfb0621e61de3167ddd9972fbc41eda92f4d9c" + }, + "include_deps": { + "context/continue_generation_example.py": "29c33a967bcdf4fa0037e1c7b0ec699c00027606dbe9d93fa4d1434f9c16c19e", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/postprocess_example.py": "b98362e6ffb84ae7826dad27d0854e30706f3993266314439859986b32ecd0bd", + "context/preprocess_example.py": "e7082a4a9ef830048ff32ed774a3e74da1cf4662a22115e6bd5543e1b9cdbf43", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/unfinished_prompt_example.py": "5d4d74064e5b845391f035fb8631903ec2f39a54a90713f9c13dc24d2eb73c4f" + } +} \ No newline at end of file diff --git a/.pdd/meta/context_snapshot_python.json b/.pdd/meta/context_snapshot_python.json index b3f00193bd..441bbe849e 100644 --- a/.pdd/meta/context_snapshot_python.json +++ b/.pdd/meta/context_snapshot_python.json @@ -1,12 +1,13 @@ { - "pdd_version": "0.0.266", - "timestamp": "2026-06-09T01:03:49.414629+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.366821+00:00", "command": "test", "prompt_hash": "d0da42dec926cca9da0b6ac499a2764830e30016e9a24f5749677a90fb976b3f", "code_hash": "6aa1ea0d41f73c40b02b72603f6193d4b6e51fdefb57d62f501311365a9ab1b8", "example_hash": "91a9137de063da9671886f64be60bf572b100e5e4f2ca380a4e49d34fb5b988e", "test_hash": "dfc29bc3df0886ab730f2c37cd5e222e09a2ab3552afaa55fc045b0ee5743b36", "test_files": { + "test_context_snapshot.py": "dfc29bc3df0886ab730f2c37cd5e222e09a2ab3552afaa55fc045b0ee5743b36", "test_context_snapshot_policy.py": "123557c02253b3cf88a5f17daddf0ca71b41e7cada231054152afb9530f9a014", "test_context_snapshot_replay.py": "6e492182f15054d5abd48807d984be1ce2d671687d458175a8be6c382a498fc4" }, diff --git a/.pdd/meta/continue_generation_python.json b/.pdd/meta/continue_generation_python.json new file mode 100644 index 0000000000..ed5c0f7cda --- /dev/null +++ b/.pdd/meta/continue_generation_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.367881+00:00", + "command": "fix", + "prompt_hash": "d8542e8a2dc3de4d0ceef1e16793504494e6827f58ded38b4944e6139d0b5a3c", + "code_hash": "900b9e3385dbb947e4358357a58176cb9bc7a81e36bf8ac7cbada9ac6cf67e07", + "example_hash": "29c33a967bcdf4fa0037e1c7b0ec699c00027606dbe9d93fa4d1434f9c16c19e", + "test_hash": "e286fcdc2b4cd6240666d230f2816de7c45f328de66d6802203ca65d2f4598e5", + "test_files": { + "test_continue_generation.py": "e286fcdc2b4cd6240666d230f2816de7c45f328de66d6802203ca65d2f4598e5" + }, + "include_deps": { + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/unfinished_prompt_example.py": "5d4d74064e5b845391f035fb8631903ec2f39a54a90713f9c13dc24d2eb73c4f", + "context/change/17/continue_generation.py": "6d48786ab0ae7ac29cb5852dfca0de6af5363657967f82e99d009ae0a042d97a", + "context/change/18/code_generator.py": "c2df2d5c6852d547b62ac13ba50e6cd63cfce7e86431ee0e73c678660f9ce9e7" + } +} \ No newline at end of file diff --git a/.pdd/meta/contract_check_python.json b/.pdd/meta/contract_check_python.json new file mode 100644 index 0000000000..d420f56032 --- /dev/null +++ b/.pdd/meta/contract_check_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.368400+00:00", + "command": "fix", + "prompt_hash": "31835ff8ff5462b9781926cf3b31b7c48ffccf56c338241ee55621fc2bfe9781", + "code_hash": "5c168f2c45b6754acce9b7fd50730c1832053df160b5de88f064061333b84f1a", + "example_hash": null, + "test_hash": "53e93d8558d08f62bef9c3ee67aa45d7c0e0a3db142f94766e5afe0e65993f71", + "test_files": { + "test_contract_check.py": "53e93d8558d08f62bef9c3ee67aa45d7c0e0a3db142f94766e5afe0e65993f71" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/contract_ir_python.json b/.pdd/meta/contract_ir_python.json new file mode 100644 index 0000000000..82da96acde --- /dev/null +++ b/.pdd/meta/contract_ir_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.368822+00:00", + "command": "fix", + "prompt_hash": "92eb68b7fdc9a1b3fdb9c4f85ddc7e91d2aa9706c93da9915bd0b246dc792e24", + "code_hash": "0d3392ec8990ac0ff6ddb4a00fee3c6719395f046a59a263ade7d8676e3648e9", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/core_cli_python.json b/.pdd/meta/core_cli_python.json new file mode 100644 index 0000000000..40a41e53d1 --- /dev/null +++ b/.pdd/meta/core_cli_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.369721+00:00", + "command": "fix", + "prompt_hash": "172c853810b5b5005c10461da3014d38eea67f70fef2c3a6312eeac96eae8553", + "code_hash": "fbdda9757fb6a4fd4be14ac670d4d79a3d2fdcc145ba1623fa63f85c1f6d7afa", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/auto_update_example.py": "4fc8ab0da96c0e8abe793d195dbc64b6b9771631be818eecde059769e5914fc9", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6" + } +} \ No newline at end of file diff --git a/.pdd/meta/core_cloud_python.json b/.pdd/meta/core_cloud_python.json index b95c1a6f18..0311f131ca 100644 --- a/.pdd/meta/core_cloud_python.json +++ b/.pdd/meta/core_cloud_python.json @@ -1,17 +1,19 @@ { - "pdd_version": "0.0.228", - "timestamp": "2026-05-06T03:28:21.404249+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.370854+00:00", "command": "regenerate-public", - "prompt_hash": "49fbb650d8825497c6ae5df53529bc7e1dc7b20d109c8e20f8016ec139c0f91e", - "code_hash": "ba9a9df53edd5b1b17f855992d9144187b5fc76231af8b9a9ac1c6fe66511b73", + "prompt_hash": "6055e3d124f3f4d5af83ec67ece60ee2653e0522f01e215d2b3c6f68dabceba8", + "code_hash": "0487c0b989996af144df3af1c818a6eeafe52fd209710e5a54eb43990c89ae97", "example_hash": "8a14ae9e69dbccfbbfffd9bde1ea11192334a10aaf9d5b5e6dba5ac23ba0dd90", - "test_hash": "4a745fb082f574b002076290ba6efc63d6e6da2e9cb32ed26608eac084acea2a", + "test_hash": "cc7c747045ad3b0e491b00ca993e66ba2c5d1144b8f7b03052df70851fc366d5", "test_files": { - "test_cloud.py": "4a745fb082f574b002076290ba6efc63d6e6da2e9cb32ed26608eac084acea2a" + "test_cloud.py": "cc7c747045ad3b0e491b00ca993e66ba2c5d1144b8f7b03052df70851fc366d5" }, "include_deps": { "context/_keyring_timeout_example.py": "41f83d5ef117caba86b788f69b519f7e88f3d7dc2a641a017d74a7cee9be6ed1", + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/core/errors_example.py": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", "context/core/utils_example.py": "ecda9cd9c5910246e0f857eacacac6ec381eb531695e5a56670a9dd8c02c0ef1", - "context/python_preamble.prompt": "57a3e51f529024ec0cb9658cd6ac61a7c8051ba0c8e887b31cf00b2e78a07d83" + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_dump_python.json b/.pdd/meta/core_dump_python.json new file mode 100644 index 0000000000..310f7a9b76 --- /dev/null +++ b/.pdd/meta/core_dump_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.371859+00:00", + "command": "fix", + "prompt_hash": "ba2ac1af773b8c0e92594e6929fae405b34369a2e79d05f9bf5ab16e5a59b309", + "code_hash": "16e6786e459f4d82e38e909fa93ce5eef7b6b4284eef6dcaa3bab99f21406421", + "example_hash": "0416a935ac490b958ceedfc6e68c7fbd7e383966374ba13ccf7ebfeaf8ad0803", + "test_hash": null, + "test_files": {}, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/core_duplicate_cli_guard_python.json b/.pdd/meta/core_duplicate_cli_guard_python.json new file mode 100644 index 0000000000..9f9cc290a8 --- /dev/null +++ b/.pdd/meta/core_duplicate_cli_guard_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.373136+00:00", + "command": "fix", + "prompt_hash": "f041d7a7d8825a0f61eba4f523cfe32cd71089dfeb4db7831b1b8e99280b7451", + "code_hash": "26ff24c97640c5818897f00cc5648708ffc719d6d7f113d24551662b9d724141", + "example_hash": "947ec40a9a778e302a6d217b16ce7e65df82cda777c3361915cc635ba106de83", + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "context/agentic_test_orchestrator_example.py": "473901f6f62844c81a047fa69387c4116d91a522c62d5c6ad30188e2e99dfaa5", + "context/architecture_registry_example.py": "5eff404eddcfb9d898df972d703013b7124d352e5fe898a1977d7986ef17ed1e", + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "pdd/architecture_registry.py": "5722225846b9cc8189b410a78e5714b4f2916d5748271d27f6f738692429c309" + } +} \ No newline at end of file diff --git a/.pdd/meta/core_errors_python.json b/.pdd/meta/core_errors_python.json new file mode 100644 index 0000000000..2a4aae2601 --- /dev/null +++ b/.pdd/meta/core_errors_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.374044+00:00", + "command": "fix", + "prompt_hash": "194ae5da34a2e913c0ab79597260d30f58f1efcf96f221ba73191fcc8ce898e4", + "code_hash": "fee544cef7641ad0b326790a4e90cc9d662a4bfcb01fac75aeb910ff85e56b84", + "example_hash": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", + "test_hash": null, + "test_files": {}, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/core_remote_session_python.json b/.pdd/meta/core_remote_session_python.json new file mode 100644 index 0000000000..9196091386 --- /dev/null +++ b/.pdd/meta/core_remote_session_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.374470+00:00", + "command": "fix", + "prompt_hash": "cbfe9e8449a09296501889ea92a9a2cae7b5743592ad2632b139e5423c1bab77", + "code_hash": "163292e0200246767f685e9478c8ab4531c06ba471be4ceb9a6ee8065b1cfc12", + "example_hash": null, + "test_hash": "1705a65e3662a75acce9df73888da9de0e1cf3a4e6f2fa72db343dcd959ebbc3", + "test_files": { + "test_remote_session.py": "1705a65e3662a75acce9df73888da9de0e1cf3a4e6f2fa72db343dcd959ebbc3" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/core_utils_python.json b/.pdd/meta/core_utils_python.json new file mode 100644 index 0000000000..99e3e205a9 --- /dev/null +++ b/.pdd/meta/core_utils_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.375386+00:00", + "command": "fix", + "prompt_hash": "24a3f952031edaa22704f965c69225836e65dc4827a838775d17e7728f181bc8", + "code_hash": "4386b3c9efd08ba0510aa80150b579f203fe9dbc32e047712599a34f55537191", + "example_hash": "ecda9cd9c5910246e0f857eacacac6ec381eb531695e5a56670a9dd8c02c0ef1", + "test_hash": null, + "test_files": {}, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/coverage_contracts_python.json b/.pdd/meta/coverage_contracts_python.json new file mode 100644 index 0000000000..3eb7041b78 --- /dev/null +++ b/.pdd/meta/coverage_contracts_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.375769+00:00", + "command": "fix", + "prompt_hash": "044980f2b8fe2bd1c0a3c294322b4e8767d9f12f8bb24410ba6e4ed818465dd8", + "code_hash": "dc209452c683697866e133c5673a2caba1828c9e4836e012f277e0250a643c0c", + "example_hash": null, + "test_hash": "ff6a64280a643dbfbec192aa22bbceb9ef6c9dacbec8ed73f58d1a666bcb9e93", + "test_files": { + "test_coverage_contracts.py": "ff6a64280a643dbfbec192aa22bbceb9ef6c9dacbec8ed73f58d1a666bcb9e93" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/crash_main_python.json b/.pdd/meta/crash_main_python.json new file mode 100644 index 0000000000..035895357e --- /dev/null +++ b/.pdd/meta/crash_main_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.376863+00:00", + "command": "fix", + "prompt_hash": "a2b233c48783a94be5b4e746a8267b114a0198702ed0f69e0357fc9b8164508d", + "code_hash": "bab5a25767957060eded0b59efc275da7f76acc173a23ec943c08a36c4eb2764", + "example_hash": "5c9b909107f74f773ccf7013d556a5812643d2a3b086e79fe07da7ea7877458c", + "test_hash": "aaf36bd8c512e712a3f276438fad35b2a2427564a2f1b85f46ab9f17e47f05c1", + "test_files": { + "test_crash_main.py": "aaf36bd8c512e712a3f276438fad35b2a2427564a2f1b85f46ab9f17e47f05c1" + }, + "include_deps": { + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/fix_code_loop_example.py": "c512f0f317474550a9ed74b5211ae0eab62c3f04115db14af67a88033aacfa87", + "context/fix_code_module_errors_example.py": "f35244d6e920711044fee92ade984f3e820a0fbfe766fd3d49718cbcfe793e60", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/detect_change_main_python.json b/.pdd/meta/detect_change_main_python.json new file mode 100644 index 0000000000..005d6cc3ac --- /dev/null +++ b/.pdd/meta/detect_change_main_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.378309+00:00", + "command": "fix", + "prompt_hash": "1e20741ae1a6daf3aaa48ab3ea0a245c9e463b503234fef18a0c5343ab39729b", + "code_hash": "2ef7a1859b4195c37e441c7ec79c00cfdff81f68af80dc277a4ee88b586d923a", + "example_hash": "ddc494709d127398004f53de58bede388692b2839a97b26668c55575369d9edd", + "test_hash": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6", + "test_files": { + "test_detect_change_main.py": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/detect_change_example.py": "44d0c9172db01bd645d48a11a7afa527a7e509f5aac911fa41ed091d3f982096" + } +} \ No newline at end of file diff --git a/.pdd/meta/detect_change_python.json b/.pdd/meta/detect_change_python.json new file mode 100644 index 0000000000..1a01cfbabd --- /dev/null +++ b/.pdd/meta/detect_change_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.380199+00:00", + "command": "fix", + "prompt_hash": "74aafd447bc746f4ea46fbd2bce19b9824803689714266c58f6724e31225ae61", + "code_hash": "46a3bf79582e6f88dc13f23183c0a8a871cbcfc4fd7e6ef98fccb49e90ca908c", + "example_hash": "44d0c9172db01bd645d48a11a7afa527a7e509f5aac911fa41ed091d3f982096", + "test_hash": "df46c280fdddde6da3943f8b058dabb79f5d22889f3a338f672b961919f49455", + "test_files": { + "test_detect_change.py": "df46c280fdddde6da3943f8b058dabb79f5d22889f3a338f672b961919f49455", + "test_detect_change_main.py": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6" + }, + "include_deps": { + "context/continue_generation_example.py": "29c33a967bcdf4fa0037e1c7b0ec699c00027606dbe9d93fa4d1434f9c16c19e", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/unfinished_prompt_example.py": "5d4d74064e5b845391f035fb8631903ec2f39a54a90713f9c13dc24d2eb73c4f", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/postprocess.py": "628880a68346c3c1bd8326b4d1b495452578937ed97b27234ad56ba332c4c2ed", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/durable_sync_runner_python.json b/.pdd/meta/durable_sync_runner_python.json index cc5f8fafc2..890da34317 100644 --- a/.pdd/meta/durable_sync_runner_python.json +++ b/.pdd/meta/durable_sync_runner_python.json @@ -1,18 +1,18 @@ { - "pdd_version": "0.0.275.dev3", - "timestamp": "2026-06-16T02:09:40.279393+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.381366+00:00", "command": "fix", - "prompt_hash": "607af0a8fd816de522eed6823ffa1865e52fd97893ea7a1d2c62381f3aaa1681", - "code_hash": "b95c3f7c268f7e91650068af248a25ad89ac9c133673c550cace9e22c4079265", + "prompt_hash": "33674ac16f38437372bccd6d7b6d6b1c720528a4f6f4c358cfb78c34e2441ede", + "code_hash": "9bf0265a38b57f44c5c5f9962d55d6f5e17792b6217cf5749d65c2e123985392", "example_hash": null, - "test_hash": "088d55daf37c57130e44c01d4e13fd2f259e2a83dba229f693aa2653abcd15dd", + "test_hash": "e3daa0813fc26b59eb50dc3f74ea395684a4f171c1342417fb68a190fdbb407e", "test_files": { - "test_durable_sync_runner.py": "088d55daf37c57130e44c01d4e13fd2f259e2a83dba229f693aa2653abcd15dd" + "test_durable_sync_runner.py": "e3daa0813fc26b59eb50dc3f74ea395684a4f171c1342417fb68a190fdbb407e" }, "include_deps": { - "context/agentic_sync_example.py": "9bcc2f199a1463e8c424d8210ea6d5f34ad6fb5fcb1022aa879a9ecba0f8d5d6", + "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", "context/agentic_sync_runner_example.py": "fcb36209abb5ab882ad551754fb574d62509c968f8c564e18163be7f2b7ef35a", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/sync_order_example.py": "b4eb1e167e7604c7dbac703bdcba7287188fa9d2d5ef6d490216d003cdc542fa" } -} +} \ No newline at end of file diff --git a/.pdd/meta/edit_file_python.json b/.pdd/meta/edit_file_python.json new file mode 100644 index 0000000000..82d18e1799 --- /dev/null +++ b/.pdd/meta/edit_file_python.json @@ -0,0 +1,11 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.381713+00:00", + "command": "fix", + "prompt_hash": "7617636b78e26e2ff2ab2840a087435689a14dda5e8a5e6304ff75af2c7a6364", + "code_hash": "f85859f8a18a6243db9edd331620e79e8b0f2e1ddb6ca99fb5e9f4228b38fbdd", + "example_hash": "272d1967123c63800bb6afff073cf409edd71e598bcd904fa9852e0a482f87e3", + "test_hash": null, + "test_files": {}, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/embed_retrieve_python.json b/.pdd/meta/embed_retrieve_python.json new file mode 100644 index 0000000000..89b1da1074 --- /dev/null +++ b/.pdd/meta/embed_retrieve_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.382194+00:00", + "command": "fix", + "prompt_hash": "555494744ac9cac860b021a4f122449a6a67be1a9388f23a7ac8ca47f0f47603", + "code_hash": "86834b149d6112a05bd2b98f38878c4d967d0667e9722ed7ce43f5217f98729e", + "example_hash": "17920a5c72ada21b31f6df15d9ad156d67ebaf8f141c3839b068d9379360cd84", + "test_hash": "601a45693322f01348ab0958c18a6627bb880e8f0da87acc9ca5d4fbe1984497", + "test_files": { + "test_embed_retrieve.py": "601a45693322f01348ab0958c18a6627bb880e8f0da87acc9ca5d4fbe1984497" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/evidence_manifest_python.json b/.pdd/meta/evidence_manifest_python.json new file mode 100644 index 0000000000..53c8770029 --- /dev/null +++ b/.pdd/meta/evidence_manifest_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.382671+00:00", + "command": "fix", + "prompt_hash": "272555690e7df823d17bb5729d7f2ae871b27af13aa4109c533e3c9dbd289792", + "code_hash": "8f468855a9a9f997b73147b37cf937d1594dacf147c7e2ec34565099a9f1e40b", + "example_hash": null, + "test_hash": "ead52731d4af649d05635fbfab7ff9e7007cb1d2f761aa556e51f84f3f425944", + "test_files": { + "test_evidence_manifest.py": "ead52731d4af649d05635fbfab7ff9e7007cb1d2f761aa556e51f84f3f425944" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/evidence_store_python.json b/.pdd/meta/evidence_store_python.json new file mode 100644 index 0000000000..230fbcbfd5 --- /dev/null +++ b/.pdd/meta/evidence_store_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.383026+00:00", + "command": "fix", + "prompt_hash": "5083989f11139a52428b6b58b8f6d9126d4aa75afd54a0af03d3a676ec73dc69", + "code_hash": "eccc499c6f076b52e4b481a07904b9390120e52c49cb2479adbdf5eb433df14c", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/extracts_prune_python.json b/.pdd/meta/extracts_prune_python.json new file mode 100644 index 0000000000..8b9ed55d5e --- /dev/null +++ b/.pdd/meta/extracts_prune_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.383898+00:00", + "command": "fix", + "prompt_hash": "1c1743a61d7690b35115be3fbabbaa5bc55e1268b74efa7b0af5ce782f29c571", + "code_hash": "0bc2ebd73806ce23453c8b97a763891a8c045c3d9214edd0a719b8fc328c0a06", + "example_hash": "b8a894f24d715f42be14b9977b6c091e75401e3f46f0722703fa63b61b26a7ee", + "test_hash": "9be47ef7359ee64d009cc03612f1e196a35d535a815e29012193eacad5aa52df", + "test_files": { + "test_extracts_prune.py": "9be47ef7359ee64d009cc03612f1e196a35d535a815e29012193eacad5aa52df" + }, + "include_deps": { + "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", + "context/include_query_extractor_example.py": "83c8b945de75bd49b258f4feabbdda3d9c08a06ad9afca3e90df7534f68a34aa", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/failure_classification_python.json b/.pdd/meta/failure_classification_python.json index 4d38774775..eaf25994a1 100644 --- a/.pdd/meta/failure_classification_python.json +++ b/.pdd/meta/failure_classification_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.274", - "timestamp": "2026-06-16T01:06:08.613980+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.384471+00:00", "command": "fix", "prompt_hash": "f4a1ca1b51cb57f7c8513109c6f17e181045166075daf11d973d31cc495af816", "code_hash": "0675857d23f52e447f15ace22ec37c2f003a61d3c810254c8547129c29d697ff", diff --git a/.pdd/meta/find_section_python.json b/.pdd/meta/find_section_python.json new file mode 100644 index 0000000000..44d5feae90 --- /dev/null +++ b/.pdd/meta/find_section_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.384903+00:00", + "command": "fix", + "prompt_hash": "30b22c834c4a659be69878bef0d3cea6f7cf75c93e6dc9f3e585a7a4cbb564b5", + "code_hash": "973fc53d8e0a0c24401a52f5a565598aeb5436fec4e0ab0314afb2983580fc47", + "example_hash": "681043403aa02b9eb0d265a95560fce565507d0656d1693f79650f8eb5f0683a", + "test_hash": "916c5c0598cf1687a3d83aa6abacea5c53efe278df211d834e2f731097b979e7", + "test_files": { + "test_find_section.py": "916c5c0598cf1687a3d83aa6abacea5c53efe278df211d834e2f731097b979e7" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/firecrawl_cache_python.json b/.pdd/meta/firecrawl_cache_python.json new file mode 100644 index 0000000000..c6be84faee --- /dev/null +++ b/.pdd/meta/firecrawl_cache_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.385405+00:00", + "command": "fix", + "prompt_hash": "1b8c25255fc1387765e986b0775379102e71c71c7e0b90076c65822992162894", + "code_hash": "4b5ffcf7246451bf1c60f86594dda44e4eeeb89778a56e0a400ba35dd17e1677", + "example_hash": null, + "test_hash": "3bfaeaed94c1f594f11291f7cdf837e0d6abc96c97b85e3d62dee88dc439f5cb", + "test_files": { + "test_firecrawl_cache.py": "3bfaeaed94c1f594f11291f7cdf837e0d6abc96c97b85e3d62dee88dc439f5cb" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/fix_code_loop_python.json b/.pdd/meta/fix_code_loop_python.json index 9bac79604f..26bef435ab 100644 --- a/.pdd/meta/fix_code_loop_python.json +++ b/.pdd/meta/fix_code_loop_python.json @@ -1,10 +1,10 @@ { - "pdd_version": "0.0.228", - "timestamp": "2026-05-06T03:28:21.485952+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.386504+00:00", "command": "regenerate-public", - "prompt_hash": "947f0f0d054800b620cc2174bf96a8658fa4687190e9e4e50f23e39d1f91c1d0", + "prompt_hash": "6a32dcc711f1e24de6b23d4a498bd00b1d41ab058d4fd64dfc3b76ea42d8dc94", "code_hash": "3bff0fb82111513ed5aa32c33bd80578c7178e871f818be1b01635b7a2b185b1", - "example_hash": null, + "example_hash": "c512f0f317474550a9ed74b5211ae0eab62c3f04115db14af67a88033aacfa87", "test_hash": "bc1f4f81af211623bcb2539cc4761f7e5ccb6926aebf86cc6aefa3b152557400", "test_files": { "test_fix_code_loop.py": "bc1f4f81af211623bcb2539cc4761f7e5ccb6926aebf86cc6aefa3b152557400" @@ -14,6 +14,6 @@ "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", "context/fix_code_module_errors_example.py": "f35244d6e920711044fee92ade984f3e820a0fbfe766fd3d49718cbcfe793e60", "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", - "context/python_preamble.prompt": "57a3e51f529024ec0cb9658cd6ac61a7c8051ba0c8e887b31cf00b2e78a07d83" + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/fix_code_module_errors_python.json b/.pdd/meta/fix_code_module_errors_python.json new file mode 100644 index 0000000000..9b6edce134 --- /dev/null +++ b/.pdd/meta/fix_code_module_errors_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.387188+00:00", + "command": "fix", + "prompt_hash": "67f31fdf9d727abafe85503ac9aacc3043e1373bd87893ee97d91bbe7fcf3807", + "code_hash": "cdb5b1681cc0629f6bd28c19be5378e9a005280d606723a366a5fabc2133ed89", + "example_hash": "f35244d6e920711044fee92ade984f3e820a0fbfe766fd3d49718cbcfe793e60", + "test_hash": "6af8d3af08f9de9717e0c1f2abd2c0c0013da80fb22b9bcf8198b5ee0aae4ee0", + "test_files": { + "test_fix_code_module_errors.py": "6af8d3af08f9de9717e0c1f2abd2c0c0013da80fb22b9bcf8198b5ee0aae4ee0" + }, + "include_deps": { + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/fix_error_loop_python.json b/.pdd/meta/fix_error_loop_python.json index 1cd791ee0e..47c0a01eed 100644 --- a/.pdd/meta/fix_error_loop_python.json +++ b/.pdd/meta/fix_error_loop_python.json @@ -1,11 +1,28 @@ { - "pdd_version": "0.0.257", - "timestamp": "2026-06-02T05:32:50.786435+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.389414+00:00", "command": "example", - "prompt_hash": null, - "code_hash": null, - "example_hash": null, - "test_hash": null, - "test_files": null, - "include_deps": null + "prompt_hash": "ae052bd412593cd6bf368c6aa753852f19b7698162713431ca0e054e0b7d9c3f", + "code_hash": "8454d9d818cbc14e80f15b8d79fd790279bcdfb31bbb68b84a0611b99396c0c6", + "example_hash": "a86435e82357bc671ac6dadee6df22c163d27a30cbdba102e9cbe3bc3121fc43", + "test_hash": "6190aeff914edf5b7929874866480d44a2805956a2917afaa1fd14975c5606ae", + "test_files": { + "test_fix_error_loop.py": "6190aeff914edf5b7929874866480d44a2805956a2917afaa1fd14975c5606ae", + "test_fix_error_loop_failure_aware.py": "07cc0a1fa6055d0e27b0a01dd73883e215cb7e5c329bbe870cf97c13e3d40e1b", + "test_fix_error_loop_prompt_contract.py": "57f50dae4378256814c37cc875032e829288f9fb34687aa53b68dea39175cbca", + "test_fix_error_loop_sync_e2e.py": "a838021d92b7b0e3d2042957c82542aa8aabbb2ddc9c67d1f601817bfc397e9e" + }, + "include_deps": { + "context/agentic_fix_example.py": "407a024fcba9402e00b401477725ae72b1de718ab59bea29b69509a0b15f621f", + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "context/core/cloud_example.py": "8a14ae9e69dbccfbbfffd9bde1ea11192334a10aaf9d5b5e6dba5ac23ba0dd90", + "context/fix_errors_from_unit_tests_example.py": "df6c93b3ae585af13827cf3edb398e7c0da75648b34ff0477044b659df85a117", + "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", + "context/pytest_example.py": "f13c02d911d386ac5bab8e3d4aae64a768e4a7e960803c80fcac14e9ba5975cb", + "context/python_env_detector_example.py": "65619b3e8bad0509f1ccf54d81b5c3760f423b6fc1925c932fc7968da78a172e", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/failure_classification.py": "0675857d23f52e447f15ace22ec37c2f003a61d3c810254c8547129c29d697ff", + "pdd/fix_focus.py": "e341e6bda871ddc5ba92cf05e9d554d49bc5e4afebf5b4f1482971edf557063d", + "pdd/test_context_packer.py": "27c7d14747d38df8edf24c8ef2ce1b7ca21d8f2eea38aec02ba06042ee144c0b" + } } \ No newline at end of file diff --git a/.pdd/meta/fix_errors_from_unit_tests_python.json b/.pdd/meta/fix_errors_from_unit_tests_python.json new file mode 100644 index 0000000000..f5ae7d1db8 --- /dev/null +++ b/.pdd/meta/fix_errors_from_unit_tests_python.json @@ -0,0 +1,21 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.391388+00:00", + "command": "fix", + "prompt_hash": "5dd9132474b83ac80334bfeefdfc55478d506da9d95acd54ddbbca97c00995a6", + "code_hash": "7ad19b3ca4b61406c1da5dcd86783a5b1aa183f9ecea231979675de6f3924404", + "example_hash": "df6c93b3ae585af13827cf3edb398e7c0da75648b34ff0477044b659df85a117", + "test_hash": "cbf129e3ab3a9f6731b197ec4641264a0cd68238123fa626dfd55b87fd20ca09", + "test_files": { + "test_fix_errors_from_unit_tests.py": "cbf129e3ab3a9f6731b197ec4641264a0cd68238123fa626dfd55b87fd20ca09" + }, + "include_deps": { + "context/change/10/initial_fix_errors_from_unit_tests.py": "7a3eb969bcaa76dc85d59c4013a41a7da5bb7472daf97df2b2cad0475642d2c7", + "context/change/16/fix_error_loop.py": "01872cfcc6c3f5095551acd109e06b35ece96c15ca75dcf40ac395c3ed867e40", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/edit_file.py": "f85859f8a18a6243db9edd331620e79e8b0f2e1ddb6ca99fb5e9f4228b38fbdd", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/fix_focus_python.json b/.pdd/meta/fix_focus_python.json new file mode 100644 index 0000000000..d6b2073e5b --- /dev/null +++ b/.pdd/meta/fix_focus_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.392102+00:00", + "command": "fix", + "prompt_hash": "5495f47b8ca32f768f25b4864a4a6bd59daae7ac21544c4ae75363e0ca6d2ee4", + "code_hash": "e341e6bda871ddc5ba92cf05e9d554d49bc5e4afebf5b4f1482971edf557063d", + "example_hash": null, + "test_hash": "3c43a5554ef2810db0466cc388f4d6a144399005613422787997777e99ea4270", + "test_files": { + "test_fix_focus.py": "3c43a5554ef2810db0466cc388f4d6a144399005613422787997777e99ea4270" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/prompts/llm_invoke_python.prompt": "88face96e298219fba7448186eb71f1586a676888a827a04d326882df8e4f41e" + } +} \ No newline at end of file diff --git a/.pdd/meta/fix_main_python.json b/.pdd/meta/fix_main_python.json new file mode 100644 index 0000000000..17bfd0fa49 --- /dev/null +++ b/.pdd/meta/fix_main_python.json @@ -0,0 +1,23 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.393900+00:00", + "command": "fix", + "prompt_hash": "aa3e9b550afbcdb9e95e2c92fddf04111709b422649cb3266e728fa8b5a38652", + "code_hash": "3f67d418500e2ec32d016c3ec50bce459e8fa05e75711b46d2a38e683347a60f", + "example_hash": "29f88d8bfcc2256ebebe6efcb611f9487eb5ca6d8781286a6dd98689f92bca7a", + "test_hash": "6a19d93c9375efa0972129a4642f5e84663dc939822bffe1543cfeda87741789", + "test_files": { + "test_fix_main.py": "6a19d93c9375efa0972129a4642f5e84663dc939822bffe1543cfeda87741789", + "test_fix_main_issue_232.py": "f33bb063df3cb570b5b46e3361cf3339be65de7fdabe249d8ba0f15893ba2207" + }, + "include_deps": { + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/change/10/initial_fix_errors_from_unit_tests.py": "7a3eb969bcaa76dc85d59c4013a41a7da5bb7472daf97df2b2cad0475642d2c7", + "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74", + "context/change/16/fix_error_loop.py": "01872cfcc6c3f5095551acd109e06b35ece96c15ca75dcf40ac395c3ed867e40", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/fix_focus.py": "e341e6bda871ddc5ba92cf05e9d554d49bc5e4afebf5b4f1482971edf557063d" + } +} \ No newline at end of file diff --git a/.pdd/meta/fix_verification_errors_loop_python.json b/.pdd/meta/fix_verification_errors_loop_python.json new file mode 100644 index 0000000000..d992bb87e0 --- /dev/null +++ b/.pdd/meta/fix_verification_errors_loop_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.395075+00:00", + "command": "fix", + "prompt_hash": "3afa1fd7d8e92ad9a2d6a5f20468ade73a9ea077adb8a01fb2dba1583cde6086", + "code_hash": "ea1649f2cafd6e7eb7db3f19489d7ac0bcc96137b9b73291b6720ba4fb38341f", + "example_hash": "0212e6010a7c163c476c3df095f6ca99414829f73df34c60651afae83633d307", + "test_hash": "ce41af1918e9b7c68ebfeb8d478eb2931fa3f8b809b05443952c8ce4f376010c", + "test_files": { + "test_fix_verification_errors_loop.py": "ce41af1918e9b7c68ebfeb8d478eb2931fa3f8b809b05443952c8ce4f376010c" + }, + "include_deps": { + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "context/agentic_verify_example.py": "1a64161baccfc035ffbd73bf99cc1888d28d8d714a49deb01a75918e3b9732f8", + "context/fix_verification_errors_example.py": "087d89544db864fe4c8025124ce2fd3fdf9f621c988bd415ba9a0ba942d2f497", + "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/fix_verification_errors_python.json b/.pdd/meta/fix_verification_errors_python.json new file mode 100644 index 0000000000..512d698f38 --- /dev/null +++ b/.pdd/meta/fix_verification_errors_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.396030+00:00", + "command": "fix", + "prompt_hash": "65f5c3f6032927203ab5722359e8b1c0ab326708dde9483408fc1c77fd85a683", + "code_hash": "5abede2b80b05cb859c83d41618c1e5bebddabfecddf7501042a9f09526fcefa", + "example_hash": "087d89544db864fe4c8025124ce2fd3fdf9f621c988bd415ba9a0ba942d2f497", + "test_hash": "3af44c3e8d2eb7e3635f935450832a6ae733dc5577c7e7d2fc1dcfc1eb673d45", + "test_files": { + "test_fix_verification_errors.py": "3af44c3e8d2eb7e3635f935450832a6ae733dc5577c7e7d2fc1dcfc1eb673d45", + "test_fix_verification_errors_loop.py": "ce41af1918e9b7c68ebfeb8d478eb2931fa3f8b809b05443952c8ce4f376010c" + }, + "include_deps": { + "context/edit_file_example.py": "272d1967123c63800bb6afff073cf409edd71e598bcd904fa9852e0a482f87e3", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/fix_verification_main_python.json b/.pdd/meta/fix_verification_main_python.json new file mode 100644 index 0000000000..c13321a95b --- /dev/null +++ b/.pdd/meta/fix_verification_main_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.397083+00:00", + "command": "fix", + "prompt_hash": "d6577292faee7ad7513ead07332c24f2a836d0b1bb8793064004d7549e240d41", + "code_hash": "42b18d666938c41e9ee58b08cfec349de715da44ace4f5e2987bc9d725f4a089", + "example_hash": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", + "test_hash": "e67998c377e5f50222458fa6da9eec72a9873f4b5181af641963b45632ded190", + "test_files": { + "test_fix_verification_main.py": "e67998c377e5f50222458fa6da9eec72a9873f4b5181af641963b45632ded190" + }, + "include_deps": { + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/fix_verification_errors_example.py": "087d89544db864fe4c8025124ce2fd3fdf9f621c988bd415ba9a0ba942d2f497", + "context/fix_verification_errors_loop_example.py": "0212e6010a7c163c476c3df095f6ca99414829f73df34c60651afae83633d307", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/gate_policy_python.json b/.pdd/meta/gate_policy_python.json new file mode 100644 index 0000000000..c81c70d736 --- /dev/null +++ b/.pdd/meta/gate_policy_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.397448+00:00", + "command": "fix", + "prompt_hash": "d489b706b3b826e8e18bba5d945a97aaa8abca83728afffcd91bd9a51b83da40", + "code_hash": "110ad068b2e5f1d4c0aa0e8ace3c8da8acb05d48f3116b6229459ed258d69667", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/generate_model_catalog_python.json b/.pdd/meta/generate_model_catalog_python.json new file mode 100644 index 0000000000..b5e181ade1 --- /dev/null +++ b/.pdd/meta/generate_model_catalog_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.397933+00:00", + "command": "fix", + "prompt_hash": "1e0ffc1fb8e8172bb396b8050c67bfbf750e28bd4191ffb63f7d664d0530827e", + "code_hash": "2c3ede9cb5b9ab319af0b7c950309a1fc0cb620a0555cef6b427b004fce1a353", + "example_hash": "44157c26beba999e90db7480ce87f26060f25cbf6cdf06643f5af9d5f8001acc", + "test_hash": "4232fde1a3d6080889f39d71389beeab6143f83732b1b510eb6a1d916eef11b9", + "test_files": { + "test_generate_model_catalog.py": "4232fde1a3d6080889f39d71389beeab6143f83732b1b510eb6a1d916eef11b9" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/generate_output_paths_python.json b/.pdd/meta/generate_output_paths_python.json new file mode 100644 index 0000000000..ded311533a --- /dev/null +++ b/.pdd/meta/generate_output_paths_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.399220+00:00", + "command": "fix", + "prompt_hash": "e71a805eb795dfbc6f31f06b5f521521ff4a7a93adce9dce95c788df49c69711", + "code_hash": "13890fe1983e3554b58f67404ce3848b3e9e329c03cf661446ad9ef62a71b43e", + "example_hash": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", + "test_hash": "c0ed9c8db22f119f3849ee3e00d8bac35b8d67fc78dfcccc5d6fefc78d1f081a", + "test_files": { + "test_generate_output_paths.py": "c0ed9c8db22f119f3849ee3e00d8bac35b8d67fc78dfcccc5d6fefc78d1f081a", + "test_generate_output_paths_regression.py": "3763968e8dc0e661e6516520f9282776ae81f82d5207633926ccee6fd60d50ba" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", + "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74" + } +} \ No newline at end of file diff --git a/.pdd/meta/generate_test_python.json b/.pdd/meta/generate_test_python.json new file mode 100644 index 0000000000..f1bffaa536 --- /dev/null +++ b/.pdd/meta/generate_test_python.json @@ -0,0 +1,26 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.401706+00:00", + "command": "fix", + "prompt_hash": "c77e5b4722100e72acb3addac1f9f2cd4e87cecc314f9ff4e984314b3d21eff6", + "code_hash": "c34164ec5abded5fbc0e600f3ad007fc6175a29d0662dded3d57edbae9e3fb17", + "example_hash": "f73533a9cf63f2e2f4818ee923a8500e612d155e230017dbdb35aec945e41998", + "test_hash": "f5f7fcc72e1cb4e7af0434ecd2dc423a27cdc71c769dd74b122582517fd66722", + "test_files": { + "test_generate_test.py": "f5f7fcc72e1cb4e7af0434ecd2dc423a27cdc71c769dd74b122582517fd66722", + "test_generate_test_llm_preprocess.py": "bd9e1c8d5c9e68cd788f0e073a8064c3957de7d427e13453fa6ce7aff2853130" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/bug_to_unit_test_example.py": "ab1d665923937f6599f78c0cac82f5d7c04a7afa092e7767d67e417e067a8817", + "context/change/12/initial_postprocess.py": "845d5ada84654630518eda1f06e372bd2af87a230077ce8078efc543b9286714", + "context/change/17/continue_generation.py": "6d48786ab0ae7ac29cb5852dfca0de6af5363657967f82e99d009ae0a042d97a", + "context/change/18/code_generator.py": "c2df2d5c6852d547b62ac13ba50e6cd63cfce7e86431ee0e73c678660f9ce9e7", + "context/continue_generation_example.py": "29c33a967bcdf4fa0037e1c7b0ec699c00027606dbe9d93fa4d1434f9c16c19e", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/unfinished_prompt_example.py": "5d4d74064e5b845391f035fb8631903ec2f39a54a90713f9c13dc24d2eb73c4f", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/postprocess.py": "628880a68346c3c1bd8326b4d1b495452578937ed97b27234ad56ba332c4c2ed", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/generation_completion_python.json b/.pdd/meta/generation_completion_python.json new file mode 100644 index 0000000000..52fc6123be --- /dev/null +++ b/.pdd/meta/generation_completion_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.402113+00:00", + "command": "fix", + "prompt_hash": "dde7e344d8f08e298359f9ef72e7b38c0badc58c47d5d1162d51a60601808fcf", + "code_hash": "8313db548a81def2265688d325e532fd1a44ac1f45c1cf65f534b15887b012b9", + "example_hash": "84f4a9f8ef36a750f6c15b4be89673d4ef6c9af5c81972173cac90f1f9876ae4", + "test_hash": "1d77ed3aa9c0d54a4d367098e24a765fb456122c9e1a681594290a00a64e912c", + "test_files": { + "test_generation_completion.py": "1d77ed3aa9c0d54a4d367098e24a765fb456122c9e1a681594290a00a64e912c" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/get_comment_python.json b/.pdd/meta/get_comment_python.json index bfc420c74b..d164d68fbc 100644 --- a/.pdd/meta/get_comment_python.json +++ b/.pdd/meta/get_comment_python.json @@ -1,10 +1,10 @@ { - "pdd_version": "0.0.228", - "timestamp": "2026-05-06T03:28:21.545972+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.402627+00:00", "command": "regenerate-public", "prompt_hash": "8ed03ff72edaea977592d8c37140fddb51fe19866589dfd9d2b5d0fcdbde5420", "code_hash": "53e70fe3e4f7ba637f7c754d95a751e068754eb06d265b1e95636349c118a883", - "example_hash": null, + "example_hash": "3293b4631db7c783d87745abf36a79996d5c182b74e8bee885a2e522550db851", "test_hash": "8bdc2cf2b963f5277960f1703ea4d90780923bfb2e37aec38322324dd3870151", "test_files": { "test_get_comment.py": "8bdc2cf2b963f5277960f1703ea4d90780923bfb2e37aec38322324dd3870151" diff --git a/.pdd/meta/get_extension_python.json b/.pdd/meta/get_extension_python.json new file mode 100644 index 0000000000..b2cc498f6c --- /dev/null +++ b/.pdd/meta/get_extension_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.403182+00:00", + "command": "fix", + "prompt_hash": "8cc4693dd0372bc8971b7e4902618a975fca012d410d403cb36b174ee2dea8c1", + "code_hash": "4f9ab4599944c8faf14fb060f83a0b6745d1d096b357de34b21c3b34a84480d7", + "example_hash": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", + "test_hash": "80bd7a246b278b7b59bf0847c4ac9e28e688ce9deb1b467b1261865c3f0613e7", + "test_files": { + "test_get_extension.py": "80bd7a246b278b7b59bf0847c4ac9e28e688ce9deb1b467b1261865c3f0613e7" + }, + "include_deps": { + "context/path_resolution_example.py": "15ba84fd11c61af8fa12dcb19d63d42f0cb09b747542bf20e69650b8ff4ac137", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/get_jwt_token_python.json b/.pdd/meta/get_jwt_token_python.json new file mode 100644 index 0000000000..64302fb086 --- /dev/null +++ b/.pdd/meta/get_jwt_token_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.403914+00:00", + "command": "fix", + "prompt_hash": "7a311e6892810f02d38a2482ee1f42cf0f5f575a394f0de2518baf4a3c45c304", + "code_hash": "93f690a01f9945f8c7434b48c52e3548764275b99c933e8952c7bf5f0a3b4316", + "example_hash": "76a87c8257cb1f4cfdc2edff6225c752432afb3a5e352fcb016d08d8eae16e01", + "test_hash": "2a3e12d31e50900171f486e4e0aafb35784a923ca240a1b6b61d4ffddc8127c0", + "test_files": { + "test_get_jwt_token.py": "2a3e12d31e50900171f486e4e0aafb35784a923ca240a1b6b61d4ffddc8127c0" + }, + "include_deps": { + "context/_keyring_timeout_example.py": "41f83d5ef117caba86b788f69b519f7e88f3d7dc2a641a017d74a7cee9be6ed1", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/get_language_python.json b/.pdd/meta/get_language_python.json new file mode 100644 index 0000000000..28e6e48a5b --- /dev/null +++ b/.pdd/meta/get_language_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.404417+00:00", + "command": "fix", + "prompt_hash": "342a9c09594784c2199ab87d52dd03e6d8b27a220c219d121b08b28efaf8c444", + "code_hash": "65004add40c93365c1cbd705a6ef24d5bda6f7016c3a67749b25e61122c50ce7", + "example_hash": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", + "test_hash": "4c358e4be326c279add6c33d30c83250b7936ad26d31eda0d895715c27fadd55", + "test_files": { + "test_get_language.py": "4c358e4be326c279add6c33d30c83250b7936ad26d31eda0d895715c27fadd55" + }, + "include_deps": { + "context/path_resolution_example.py": "15ba84fd11c61af8fa12dcb19d63d42f0cb09b747542bf20e69650b8ff4ac137" + } +} \ No newline at end of file diff --git a/.pdd/meta/get_lint_commands_python.json b/.pdd/meta/get_lint_commands_python.json new file mode 100644 index 0000000000..4268459215 --- /dev/null +++ b/.pdd/meta/get_lint_commands_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.404998+00:00", + "command": "fix", + "prompt_hash": "099f72e088fc18213c08338f23a33750ac07da246ee38b2449fe7875c46dc1ce", + "code_hash": "3f48c9f1d209d09754f53f07c6196288ae8ff0e239e8020f4b370ddf36285f45", + "example_hash": null, + "test_hash": "68fc0f98f587c85efd0f3da10f6af45c82d0eef8d0830fcf91cde89af27f24ec", + "test_files": { + "test_get_lint_commands.py": "68fc0f98f587c85efd0f3da10f6af45c82d0eef8d0830fcf91cde89af27f24ec" + }, + "include_deps": { + "context/get_test_command_example.py": "33b16476536f8c9424d3222ffc4a5cd5ecee6ad0589b2c66a4f3c7f1e265106c", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/get_run_command_python.json b/.pdd/meta/get_run_command_python.json new file mode 100644 index 0000000000..eaa6676680 --- /dev/null +++ b/.pdd/meta/get_run_command_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.405577+00:00", + "command": "fix", + "prompt_hash": "8ca93563bceca5fb9462c5cee01eb969f1c56d6bd162206a10ff0d953fd6cb78", + "code_hash": "5eec778a234abc4ace4166d71a68f6e49f1b81491962867de81f61be882a5319", + "example_hash": "4d187e844adb255c2738274556f4828728d0d73d84ebf8bda885d51d4be9414f", + "test_hash": "14eec1ffc3bac502fa314c8b9a3dcd63e99066fc1583db9c76c0c2bddb03020c", + "test_files": { + "test_get_run_command.py": "14eec1ffc3bac502fa314c8b9a3dcd63e99066fc1583db9c76c0c2bddb03020c" + }, + "include_deps": { + "context/path_resolution_example.py": "15ba84fd11c61af8fa12dcb19d63d42f0cb09b747542bf20e69650b8ff4ac137", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/get_test_command_python.json b/.pdd/meta/get_test_command_python.json index 3bab6eeb9f..07cbfec6d2 100644 --- a/.pdd/meta/get_test_command_python.json +++ b/.pdd/meta/get_test_command_python.json @@ -1,15 +1,16 @@ { - "pdd_version": "0.0.228", - "timestamp": "2026-05-06T03:28:21.593685+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.406672+00:00", "command": "regenerate-public", - "prompt_hash": "a8e7effb43b26e42006d3d2febfc38e0da7c1d53221ac4068d89b6d0c08ecfb5", + "prompt_hash": "ba7e479e5f8a3344d1e5f1694701fb6158e7ee8193b26576a5b459334e8bc683", "code_hash": "a1e871896a289049c73df4071ec48fc47792ff6cab05332816ba702cd3bc1cb6", - "example_hash": null, - "test_hash": "5d759cb5c4491420c4ee01d6973f6d0493d02cfe1cdb0bfaf8cb540a868bc365", + "example_hash": "33b16476536f8c9424d3222ffc4a5cd5ecee6ad0589b2c66a4f3c7f1e265106c", + "test_hash": "116bb2f5a7c5ae9e0715801f27749c4263554168051066635a0f66e7c95409bb", "test_files": { - "test_get_test_command.py": "5d759cb5c4491420c4ee01d6973f6d0493d02cfe1cdb0bfaf8cb540a868bc365" + "test_get_test_command.py": "116bb2f5a7c5ae9e0715801f27749c4263554168051066635a0f66e7c95409bb" }, "include_deps": { + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", "pdd/agentic_langtest.py": "7cb0be38d526d0a630500185427a9f76666d2b79385f7333a7608eb1fb33cfc9", "pdd/data/language_format.csv": "db3542c10a4c5c2a4a9bbe02558b4bd02fbb357fb243e33de4831d337484373e", "pdd/get_language.py": "65004add40c93365c1cbd705a6ef24d5bda6f7016c3a67749b25e61122c50ce7" diff --git a/.pdd/meta/git_porcelain_python.json b/.pdd/meta/git_porcelain_python.json new file mode 100644 index 0000000000..fa093e3eef --- /dev/null +++ b/.pdd/meta/git_porcelain_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.407159+00:00", + "command": "fix", + "prompt_hash": "2c95a26de29ea34f2c2f0386acc109026889e316b12e7573fcdfce342907459a", + "code_hash": "b10bbce7f1bb04079472bf76c36a4aef208bdf497a8922af224a69cb16717814", + "example_hash": null, + "test_hash": "0b07fd3d4859a21b88df03f4145dca9026de9f6bc83915340ae03b3518c31d0c", + "test_files": { + "test_git_porcelain.py": "0b07fd3d4859a21b88df03f4145dca9026de9f6bc83915340ae03b3518c31d0c" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/git_update_python.json b/.pdd/meta/git_update_python.json index 9db3f4fb85..8ca2b2bf4b 100644 --- a/.pdd/meta/git_update_python.json +++ b/.pdd/meta/git_update_python.json @@ -1,17 +1,17 @@ { - "pdd_version": "0.0.228", - "timestamp": "2026-05-06T03:28:21.639062+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.407926+00:00", "command": "regenerate-public", - "prompt_hash": "e72e5e77e584584087eab387348fde20d1e8bbbb84a9be9dfac78a5f027141e2", + "prompt_hash": "0aca4d865e12f462ee930a445fbd8d376bde2efa0ba9a5a6b57877d80f91f714", "code_hash": "ca810925f80b85596c0f1f84b4a7c052ff19a8530d24ed6989730467df2a3f17", - "example_hash": null, + "example_hash": "811304cee2cb890879ee68a816aed49dff2e7b50cfdca3125e16e0ae99819574", "test_hash": "5522f599ed1b3734d7e8097160813671f9ed10e7224fec8f46799a8389ff6ba8", "test_files": { "test_git_update.py": "5522f599ed1b3734d7e8097160813671f9ed10e7224fec8f46799a8389ff6ba8" }, "include_deps": { - "context/agentic_update_example.py": "dafed5c5980cce43f16f6828ef45f76e3fdd4ee8a41d21e53cea846b2b6dca33", - "context/python_preamble.prompt": "57a3e51f529024ec0cb9658cd6ac61a7c8051ba0c8e887b31cf00b2e78a07d83", + "context/agentic_update_example.py": "967254cd1c636ac5ba09afa0446312ffc1f28d3041ed453a4c6588c931f722c4", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/update_prompt_example.py": "56b9d8c7aa823c2996a3dc5741a47844e223bfd088366d74e48b6a099b5a11c4" } } \ No newline at end of file diff --git a/.pdd/meta/grounding_policy_python.json b/.pdd/meta/grounding_policy_python.json new file mode 100644 index 0000000000..fa460ef377 --- /dev/null +++ b/.pdd/meta/grounding_policy_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.408337+00:00", + "command": "fix", + "prompt_hash": "e9ff88e848dcdcd473657d892478bacf4ab76c09f39378cb6a3d3a43578db91d", + "code_hash": "76dfda96180a84f8efaa3836ed4a5b4fccaf16f69d12c72006d4ec89529e8cca", + "example_hash": null, + "test_hash": "43315e1f8058649cda8d9b018d793dadbaecb14b8758d23014502596204562af", + "test_files": { + "test_grounding_policy.py": "43315e1f8058649cda8d9b018d793dadbaecb14b8758d23014502596204562af" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/include_query_extractor_python.json b/.pdd/meta/include_query_extractor_python.json new file mode 100644 index 0000000000..625961bcf3 --- /dev/null +++ b/.pdd/meta/include_query_extractor_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.409908+00:00", + "command": "fix", + "prompt_hash": "369d47b3113a0645885716e99e00eb6474834b38a91e30fa30b7625d53afcf0b", + "code_hash": "fa95489a0b7b8f3ad6e887844fe14f38350e56b3d2fc2e4add08318334bcd191", + "example_hash": "83c8b945de75bd49b258f4feabbdda3d9c08a06ad9afca3e90df7534f68a34aa", + "test_hash": "732d96c26df09674d07bce08f5e797c375025f0e9f2d9151d977f7d221dbc1dc", + "test_files": { + "test_include_query_extractor.py": "732d96c26df09674d07bce08f5e797c375025f0e9f2d9151d977f7d221dbc1dc" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/load_prompt_template.py": "903bb43e90d778fa04ba42cd8e329ac42e1b419bb372268f5955f26de43cce47", + "pdd/path_resolution.py": "7bcc2c4d994a9540b65f9dbd426787709c7ad012191e9ee2da20bb3db21faffb", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/increase_tests_python.json b/.pdd/meta/increase_tests_python.json new file mode 100644 index 0000000000..39ddbd6a6c --- /dev/null +++ b/.pdd/meta/increase_tests_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.410722+00:00", + "command": "fix", + "prompt_hash": "ae3160a949d20da81e12d62a0129c1b8e3b0d7b2073c97536d25cfd258a94abe", + "code_hash": "ebc70cf5dd42a5a2cb9b6212169270dfdc5b463b1fc31c12d3ac80c11a140879", + "example_hash": "f53be429e9a9e6a523c770ed6d0d4498e2201b22d5a8e4ef28ac64e8ff172c91", + "test_hash": "a87d41f02d445cc713056b4c16a1aa4a1e3ca599db7b127d14ed84ee744d7374", + "test_files": { + "test_increase_tests.py": "a87d41f02d445cc713056b4c16a1aa4a1e3ca599db7b127d14ed84ee744d7374" + }, + "include_deps": { + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/postprocess_example.py": "b98362e6ffb84ae7826dad27d0854e30706f3993266314439859986b32ecd0bd", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/incremental_code_generator_python.json b/.pdd/meta/incremental_code_generator_python.json new file mode 100644 index 0000000000..b66ee1c021 --- /dev/null +++ b/.pdd/meta/incremental_code_generator_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.411982+00:00", + "command": "fix", + "prompt_hash": "e2bfbfc77a1dee1e4b393a6f9b377de31f07b6a0ab2693153455366467180b1b", + "code_hash": "8dd5dd7f3016b8fae86056484fdc49b824405cdcd6911e8b8657d3e043b3b06d", + "example_hash": "f6cd628ddc2c10853a15c449b32451a1290d2457942d642989678720bc0cea82", + "test_hash": "38b440d47fa99aa72101a9ed7d81d8371c714e60c2b65101de2644aac9a83a05", + "test_files": { + "test_incremental_code_generator.py": "38b440d47fa99aa72101a9ed7d81d8371c714e60c2b65101de2644aac9a83a05" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/postprocess_example.py": "b98362e6ffb84ae7826dad27d0854e30706f3993266314439859986b32ecd0bd", + "context/preprocess_example.py": "e7082a4a9ef830048ff32ed774a3e74da1cf4662a22115e6bd5543e1b9cdbf43" + } +} \ No newline at end of file diff --git a/.pdd/meta/incremental_prd_architecture_python.json b/.pdd/meta/incremental_prd_architecture_python.json new file mode 100644 index 0000000000..e7cf1c9702 --- /dev/null +++ b/.pdd/meta/incremental_prd_architecture_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.413146+00:00", + "command": "fix", + "prompt_hash": "1d30710eab8191e5a651513484774f60603091ccc97fa9518ec2aef35b1d5a49", + "code_hash": "96f56cca2ab0ce86ec389e77057421d9d972d9fff9b937d60fcca92aac6adf9b", + "example_hash": null, + "test_hash": "f916a659d90399dbeb54e93d89fc21664bb1a6cc7ca6e24046ec24a0e32e4e1b", + "test_files": { + "test_incremental_prd_architecture.py": "f916a659d90399dbeb54e93d89fc21664bb1a6cc7ca6e24046ec24a0e32e4e1b", + "test_incremental_prd_architecture_real.py": "5ee10fda3e99b8c8ab3e7e51b83ee93bac711ac3a7655c7eefb833ad4404e2ef" + }, + "include_deps": { + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/change_example.py": "cc5f850c8e41a8c5b82c94b6667975d1811dff1f51888bb8caf4ff69815f8352", + "context/detect_change_example.py": "44d0c9172db01bd645d48a11a7afa527a7e509f5aac911fa41ed091d3f982096", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/insert_includes_python.json b/.pdd/meta/insert_includes_python.json new file mode 100644 index 0000000000..e2275899fd --- /dev/null +++ b/.pdd/meta/insert_includes_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.414436+00:00", + "command": "fix", + "prompt_hash": "c91a10b91e1df2f4fa1d8cce5fb3e3a98b7632497153c9f181a20c77df00a4c7", + "code_hash": "6aaac12e5b791d63a1223d711a89b49e1d7eba4eb6dbf60c2273c608c6c73307", + "example_hash": "c304bf4656f75fa26192c92b3eb0422a903d8a1bc82dda3158dc9f184b337873", + "test_hash": "23acdecc0cf99af1b1fe67fb9115304e40f4e80b5d9bb94eaaadbbddcc1acaca", + "test_files": { + "test_insert_includes.py": "23acdecc0cf99af1b1fe67fb9115304e40f4e80b5d9bb94eaaadbbddcc1acaca" + }, + "include_deps": { + "context/auto_include_example.py": "0c278ed716298149777bc7082827eb8aa6d80dac264c66b6cded6871232f2df7", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/preprocess_example.py": "e7082a4a9ef830048ff32ed774a3e74da1cf4662a22115e6bd5543e1b9cdbf43", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/install_completion_python.json b/.pdd/meta/install_completion_python.json new file mode 100644 index 0000000000..c5b454b917 --- /dev/null +++ b/.pdd/meta/install_completion_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.415176+00:00", + "command": "fix", + "prompt_hash": "195b5686fa2baa0e4c63549f75ebc9e7bb7eaeeec3b9f32a9043c3fc202c506e", + "code_hash": "6cb309b8c3810efb049c3014a6088f7ac3511a163f22f06fcfc66f99b4f33f8a", + "example_hash": "999be17c0ce476845d7048a1a909ad425e60c298dbc7c74f51b596ef134a8aec", + "test_hash": "56947546867a8e09632bef8249b84743ec2f578890db958c7dcb7e151f48719d", + "test_files": { + "test_install_completion.py": "56947546867a8e09632bef8249b84743ec2f578890db958c7dcb7e151f48719d" + }, + "include_deps": { + "context/click_example.py": "07653c30b63c213102cf00f7c3380a5005330014e00a26342921cd85d20273c1", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/llm_invoke_python.json b/.pdd/meta/llm_invoke_python.json index 5dc5650fae..9a700a1a75 100644 --- a/.pdd/meta/llm_invoke_python.json +++ b/.pdd/meta/llm_invoke_python.json @@ -1,18 +1,19 @@ { - "pdd_version": "0.0.263.dev0", - "timestamp": "2026-06-04T20:30:11.770314+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.417870+00:00", "command": "test", - "prompt_hash": "43285448cc8f00ad6509e964509d9ec768914e02eef40f1a958bae69a60823a0", - "code_hash": "127c8cf41cdba1a5ec3865330cfba5ebbb9a582f65c19479a57fe732e33f3f2f", + "prompt_hash": "41404dff8babe6a1ff78b29f7ada4a173fcba6d8b3e0f6248c949716992d1dd2", + "code_hash": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", "example_hash": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", - "test_hash": "1979352422b5ea80ee7f2ea14a8a2c20ab880d02fd1d2365d8dd54050d2f5f18", + "test_hash": "4aaae7e8dc472e0fb280e9d773dce17ae806ee959c232badc1fb922011df1fb9", "test_files": { - "test_llm_invoke.py": "1979352422b5ea80ee7f2ea14a8a2c20ab880d02fd1d2365d8dd54050d2f5f18", + "test_llm_invoke.py": "4aaae7e8dc472e0fb280e9d773dce17ae806ee959c232badc1fb922011df1fb9", "test_llm_invoke_csv_model_registration.py": "1583b5e076fe5227a11f3d1079034ab4a21bc6131a3433f37bd68e35a99ba49e", "test_llm_invoke_grounding.py": "e219903b03ea56b821cfaaf18b8f279bdddf9d59729daf86a3456bee7bbe2ecb", "test_llm_invoke_integration.py": "2eb4bd2565761a4148762c6fb73c887cb6e12ff962742e05f5c2d4d62b47aaf9", "test_llm_invoke_nested_schema.py": "c983a19874abacc3e0ea9d6ca2ec87495960d2dd96d4e93be4039ed1bc995b9b", "test_llm_invoke_retry_cost.py": "bfdfe7b814b78813f86b8bc6d081831daf531187feff66358260f6282925958c", + "test_llm_invoke_task_routing.py": "b3bb259d14c832001e09ec865b27bfb471d572a7f43290975447cbfa863b93b7", "test_llm_invoke_vertex_retry.py": "eafe91ba9376dc7e2da36faf3cd2de3cef50f70cf1c4fc5655e373deb7f50c26" }, "include_deps": { @@ -20,6 +21,6 @@ "context/path_resolution_example.py": "15ba84fd11c61af8fa12dcb19d63d42f0cb09b747542bf20e69650b8ff4ac137", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "pdd/core/cloud.py": "0487c0b989996af144df3af1c818a6eeafe52fd209710e5a54eb43990c89ae97", - "pdd/server/token_counter.py": "f784679da58bbabb9eb9b17c86f13e1ec5d98f2f2bd09407b4e1b044f83ca8a1" + "pdd/server/token_counter.py": "847ac13e3804c451aca64652877940c06b72c2fc33edc00232f1d4aa16c957e8" } } \ No newline at end of file diff --git a/.pdd/meta/load_prompt_template_python.json b/.pdd/meta/load_prompt_template_python.json new file mode 100644 index 0000000000..110e33787d --- /dev/null +++ b/.pdd/meta/load_prompt_template_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.418356+00:00", + "command": "fix", + "prompt_hash": "7621531d40ff40acbc0088160d6e48b959b88afca9dd461258c56a57ec1b42a2", + "code_hash": "903bb43e90d778fa04ba42cd8e329ac42e1b419bb372268f5955f26de43cce47", + "example_hash": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "test_hash": "2b9f85a3571946d1bda46d572c14f81add70efd1feff32ec6fb1ac42ea3a3052", + "test_files": { + "test_load_prompt_template.py": "2b9f85a3571946d1bda46d572c14f81add70efd1feff32ec6fb1ac42ea3a3052" + }, + "include_deps": { + "context/path_resolution_example.py": "15ba84fd11c61af8fa12dcb19d63d42f0cb09b747542bf20e69650b8ff4ac137" + } +} \ No newline at end of file diff --git a/.pdd/meta/logo_animation_python.json b/.pdd/meta/logo_animation_python.json new file mode 100644 index 0000000000..6bfee44f19 --- /dev/null +++ b/.pdd/meta/logo_animation_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.418883+00:00", + "command": "fix", + "prompt_hash": "f0724c74377388bfb72c6b9fb4877b65990a9cf88e7a1fa5fbdabdf3c3860a36", + "code_hash": "9fa1c95b3b85cded9cb00016dbecdbc5f8ef585611238848770541b4704e923e", + "example_hash": "f32a5cc330235c3b61fb16ac62d3ae7531c7c6dbc11af077fc79054736f0944d", + "test_hash": "063bdd4453f663f540e2d978187498e8a431096e53451aa4fd80a038167fdcf4", + "test_files": { + "test_logo_animation.py": "063bdd4453f663f540e2d978187498e8a431096e53451aa4fd80a038167fdcf4" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/metadata_sync_python.json b/.pdd/meta/metadata_sync_python.json index bba992e110..5ed74e2508 100644 --- a/.pdd/meta/metadata_sync_python.json +++ b/.pdd/meta/metadata_sync_python.json @@ -1,19 +1,19 @@ { - "pdd_version": "0.0.237", - "timestamp": "2026-05-16T20:50:00.397700+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.420359+00:00", "command": "fix", - "prompt_hash": "18e8e073748217aa9c224bea7c7e8425ea36de28f769b30684cd21033018bfab", - "code_hash": "739ace489ae1bf00a9aa696332dabce993b934047228fe0d10a1ef9145130fb2", + "prompt_hash": "8ccd27574100139772388c34fcab32fbae253154d449f1ffeead270d6c92dc8d", + "code_hash": "3afaa5a409e500b3f91aab33dacee33fae47447fba80a1702d65a33761261782", "example_hash": "704453b3386724eef225b61c48f2fe922e1a973ac211c494e1d955dd44bcca11", - "test_hash": "a1bf7b5a8ce6c671aee77fca08edd29eea86e93cce2d02871d0bd25b31591dc3", + "test_hash": "82af9e0bff7550d1f9bf46f4c6e7f4792143565e4e228d1507976f6b9fbac5f6", "test_files": { - "test_metadata_sync.py": "a1bf7b5a8ce6c671aee77fca08edd29eea86e93cce2d02871d0bd25b31591dc3" + "test_metadata_sync.py": "82af9e0bff7550d1f9bf46f4c6e7f4792143565e4e228d1507976f6b9fbac5f6" }, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", - "pdd/architecture_registry.py": "f822c4ef9d66da1dc6e6104ad3ca99d822c277423e71bb807966e4fc80f779ed", - "pdd/architecture_sync.py": "89329e32dd4d13e7b095f1b96843e383936bbc5f329e50daf006dbb12af0d54b", - "pdd/operation_log.py": "78b05aadd7656dbabb7cdd113fa84d39d32c64e4cb4322aa2ac2570d390d94ef", - "pdd/sync_determine_operation.py": "dff5e2b0628122c49305106d255e91d57446d7c768d4ae78fa4a09a619383e23" + "pdd/architecture_registry.py": "5722225846b9cc8189b410a78e5714b4f2916d5748271d27f6f738692429c309", + "pdd/architecture_sync.py": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", + "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", + "pdd/sync_determine_operation.py": "e616ac746674a9f1e8be84bf3093d5e1f45ff0175bc3767b758f2d17b2c54132" } -} +} \ No newline at end of file diff --git a/.pdd/meta/model_tester_python.json b/.pdd/meta/model_tester_python.json new file mode 100644 index 0000000000..cc02f86864 --- /dev/null +++ b/.pdd/meta/model_tester_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.420905+00:00", + "command": "fix", + "prompt_hash": "fd82b8c71a0ba03c664946897f00c969643ee2fe846a001a02c560c9d2003327", + "code_hash": "786ac21e50a29087e035af7fbbfeac05e3fc2930ec3d4916ca73774623da5384", + "example_hash": "9d33f093cdac4c100bf671e891a68c7f83e2e09e74cd65f6b53cb567d77d3cd0", + "test_hash": "2b2bbc0e90e0df80cd92d307f7f9e35572a815e4d56a92220f5fd138c5241c8a", + "test_files": { + "test_model_tester.py": "2b2bbc0e90e0df80cd92d307f7f9e35572a815e4d56a92220f5fd138c5241c8a" + }, + "include_deps": { + "context/provider_manager_example.py": "cc2bbe6cefff4ad24af4365b0c4bc2c99e672f825d12edaca7307de9c04ecfb8" + } +} \ No newline at end of file diff --git a/.pdd/meta/one_session_sync_python.json b/.pdd/meta/one_session_sync_python.json new file mode 100644 index 0000000000..730ecfe632 --- /dev/null +++ b/.pdd/meta/one_session_sync_python.json @@ -0,0 +1,20 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.423139+00:00", + "command": "fix", + "prompt_hash": "d63a4299e9dbdaf43a74f14160a021b7e31be6403eb041fe8383b429ca6ffe11", + "code_hash": "37541cc02ed9eae748f2270beb39c5a66bf098bac87bf757a3e00e382d41fcf2", + "example_hash": "f2260e5e7b558e0cf1b0cb26acb7c95072c5ffd17d19231a2455979e7d8b9556", + "test_hash": "9d58025a7360f7fb7bc846db6b2014cc6a8cdea6e64a69c4952f3a723efa4a72", + "test_files": { + "test_one_session_sync.py": "9d58025a7360f7fb7bc846db6b2014cc6a8cdea6e64a69c4952f3a723efa4a72" + }, + "include_deps": { + "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", + "context/agentic_sync_runner_example.py": "fcb36209abb5ab882ad551754fb574d62509c968f8c564e18163be7f2b7ef35a", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/agentic_common.py": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/operation_log_python.json b/.pdd/meta/operation_log_python.json new file mode 100644 index 0000000000..db8320771c --- /dev/null +++ b/.pdd/meta/operation_log_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.423839+00:00", + "command": "fix", + "prompt_hash": "d09eedd7f6b781864544d62c7f513b760a3e418b3cd29efa738a4b0ddedc52ed", + "code_hash": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", + "example_hash": "2660def7012d9b79bad3db33cf399ac603cc1c35dff0b064cbdd2638a013de1d", + "test_hash": "0ec46ea27197930ae19f0f5486d34fb7f2e3800d6b2670edd1f464e72f0ae27c", + "test_files": { + "test_operation_log.py": "0ec46ea27197930ae19f0f5486d34fb7f2e3800d6b2670edd1f464e72f0ae27c", + "test_operation_logging_e2e.py": "1fc74b2e4db145dfe21150f751d4b71a81ab0aaf1cc72e44bbe8b037f671556e" + }, + "include_deps": { + "context/sync_determine_operation_example.py": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5" + } +} \ No newline at end of file diff --git a/.pdd/meta/path_resolution_python.json b/.pdd/meta/path_resolution_python.json new file mode 100644 index 0000000000..02ad88e3ff --- /dev/null +++ b/.pdd/meta/path_resolution_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.424308+00:00", + "command": "fix", + "prompt_hash": "17ed2dc0cc1541e5267c988065f5ca4c6e077193b2f2b7420ed57acfa0c0e710", + "code_hash": "7bcc2c4d994a9540b65f9dbd426787709c7ad012191e9ee2da20bb3db21faffb", + "example_hash": "15ba84fd11c61af8fa12dcb19d63d42f0cb09b747542bf20e69650b8ff4ac137", + "test_hash": "f731aa81caf48b2ee79d16e9c93860a17c0597305d877b853473a903f521f716", + "test_files": { + "test_path_resolution.py": "f731aa81caf48b2ee79d16e9c93860a17c0597305d877b853473a903f521f716" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/pddrc_initializer_python.json b/.pdd/meta/pddrc_initializer_python.json new file mode 100644 index 0000000000..2ad36d8cc8 --- /dev/null +++ b/.pdd/meta/pddrc_initializer_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.424685+00:00", + "command": "fix", + "prompt_hash": "9399d4347fee000bf46bb4a9414f384bbcd158a8e44f6ba35dc5ef4560c0c6a9", + "code_hash": "6112573fcff622386dc139f43d2dc30d99e68a3f362784f059e771648bbb928b", + "example_hash": "3ba502fa9e2a2f438aaa890f0b654a98e5b8665253e10446acafda90f7eedad9", + "test_hash": "fd553d3478328b50bb6d6639165478da1f43ba8b4c2e901cf6de52bf7a3fd317", + "test_files": { + "test_pddrc_initializer.py": "fd553d3478328b50bb6d6639165478da1f43ba8b4c2e901cf6de52bf7a3fd317" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/pin_example_hack_python.json b/.pdd/meta/pin_example_hack_python.json index 8f159bc131..0c8e6ecadd 100644 --- a/.pdd/meta/pin_example_hack_python.json +++ b/.pdd/meta/pin_example_hack_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.234", - "timestamp": "2026-05-12T02:53:56.323298+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.426635+00:00", "command": "fix", - "prompt_hash": "77e8c17f1eb7ed4e1347312a702129bcfd8af95a985ee1ccd718291f83c93fae", + "prompt_hash": "677655b3eb5ef57bbe1f4216ce0ceb5abe7ba3ee2f5a94388c2f5bdfcb21383b", "code_hash": "c90df80316bc8339fcf9d4690ac29e4dc8ae3391e25c26c82e496b87dcd4a788", "example_hash": "34e285dedea6ad0d3f3a5539401cc7c0bf5b2181d954915963fd66cd86e54e3c", "test_hash": "7fbffec72f9941a52b4ba7efd6468330dd2a3235dc53d0bb81168ea6eb6c3a72", @@ -12,13 +12,13 @@ "include_deps": { "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", - "context/code_generator_main_example.py": "679590f0913600886d99469d8ece23fbbfe6bea2e626b0d5d2ab5fdcdc079b80", + "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", "context/context_generator_main_example.py": "77c3de786f31392540ec609d4b3942e98e996ae14c4014f5018cf2b05a560df4", "context/crash_main_example.py": "5c9b909107f74f773ccf7013d556a5812643d2a3b086e79fe07da7ea7877458c", "context/fix_main_example.py": "29f88d8bfcc2256ebebe6efcb611f9487eb5ca6d8781286a6dd98689f92bca7a", "context/fix_verification_main_example.py": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", "context/get_test_command_example.py": "33b16476536f8c9424d3222ffc4a5cd5ecee6ad0589b2c66a4f3c7f1e265106c", - "context/sync_determine_operation_example.py": "94a333b37d9875bcc9b39e22d4d00de1b196ad2f7e0fa997e6f638e153dbdfad", - "context/update_main_example.py": "b318834c648f25e6141d81f3ecac1d9da592a6bb4740500983f2b07b8a10d902" + "context/sync_determine_operation_example.py": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5", + "context/update_main_example.py": "9fe01fd19196c2604c91d101e49db849e0e1c9fabafeb2ad831a9c91b2f26416" } } \ No newline at end of file diff --git a/.pdd/meta/postprocess_0_python.json b/.pdd/meta/postprocess_0_python.json new file mode 100644 index 0000000000..967824947f --- /dev/null +++ b/.pdd/meta/postprocess_0_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.427411+00:00", + "command": "fix", + "prompt_hash": "dfb5fe2454d0270eff594b45258a05d3f55d7a0c56f4fafec6d2b6a09556a628", + "code_hash": "396d7b1b20852d812b0b25a1dad2f8b32ba1a37ab6c857f6c327a443804b74f3", + "example_hash": "2ff3f65a972fbd46519fefbb1467687c4d9f2b269e14e3810eb1a8427b1b396e", + "test_hash": "4feb11f470c15bc1edf5987e72bbbc1f7de76a9c5c9d64eafce93cd77a289c9d", + "test_files": { + "test_postprocess_0.py": "4feb11f470c15bc1edf5987e72bbbc1f7de76a9c5c9d64eafce93cd77a289c9d" + }, + "include_deps": { + "context/comment_line_example.py": "debc424d539b65aef1267888bb2eb77cf4de16745407bb5df5a18b8e2f231095", + "context/find_section_example.py": "681043403aa02b9eb0d265a95560fce565507d0656d1693f79650f8eb5f0683a", + "context/get_comment_example.py": "3293b4631db7c783d87745abf36a79996d5c182b74e8bee885a2e522550db851" + } +} \ No newline at end of file diff --git a/.pdd/meta/postprocess_python.json b/.pdd/meta/postprocess_python.json new file mode 100644 index 0000000000..0bc398b9a1 --- /dev/null +++ b/.pdd/meta/postprocess_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.428184+00:00", + "command": "fix", + "prompt_hash": "3df8ad9a21611349ce5cbb63192882f07d450736a968439868d049fcd6a10817", + "code_hash": "628880a68346c3c1bd8326b4d1b495452578937ed97b27234ad56ba332c4c2ed", + "example_hash": "b98362e6ffb84ae7826dad27d0854e30706f3993266314439859986b32ecd0bd", + "test_hash": "5b297188f029a9b15aaaaba54045508e3962190b406dc96503a417d965899912", + "test_files": { + "test_postprocess.py": "5b297188f029a9b15aaaaba54045508e3962190b406dc96503a417d965899912", + "test_postprocess_0.py": "4feb11f470c15bc1edf5987e72bbbc1f7de76a9c5c9d64eafce93cd77a289c9d" + }, + "include_deps": { + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/pre_checkup_gate_python.json b/.pdd/meta/pre_checkup_gate_python.json new file mode 100644 index 0000000000..14e4449701 --- /dev/null +++ b/.pdd/meta/pre_checkup_gate_python.json @@ -0,0 +1,21 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.430240+00:00", + "command": "fix", + "prompt_hash": "7dbedd5a5ab8690a61298f5195269f074161c6218f522bcce599768fdff949ab", + "code_hash": "9ff0bbaa18c82cf4da836126861c40936a4555b8ff972f4bceee370492f37ace", + "example_hash": "82585fac9350c3436528870c0b1d7e64228e6903cc4b5d0a62a35edecb266906", + "test_hash": "d22520612cce8bf31712ff999b5f5f45153ddcd63a4044eb82c220d4a8021f62", + "test_files": { + "test_pre_checkup_gate.py": "d22520612cce8bf31712ff999b5f5f45153ddcd63a4044eb82c220d4a8021f62" + }, + "include_deps": { + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/ci_drift_heal_example.py": "550e750fb041fb73dc92462d4f266bc999102ddd8e4efd3b40dbab0bb1d0d879", + "context/metadata_sync_example.py": "704453b3386724eef225b61c48f2fe922e1a973ac211c494e1d955dd44bcca11", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/checkup_gates.py": "b6086954a93e0495661e6ca39d96b3079b928d13308bf0fcd6a16b1e0b5f511c", + "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", + "pdd/sync_determine_operation.py": "e616ac746674a9f1e8be84bf3093d5e1f45ff0175bc3767b758f2d17b2c54132" + } +} \ No newline at end of file diff --git a/.pdd/meta/preprocess_main_python.json b/.pdd/meta/preprocess_main_python.json new file mode 100644 index 0000000000..6230508b2f --- /dev/null +++ b/.pdd/meta/preprocess_main_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.432075+00:00", + "command": "fix", + "prompt_hash": "9bdb68754d0f924602000d44462f64207853deb89659c0d9ad1538ad0e128859", + "code_hash": "a069c3a73be88d3e3e93d40fd66e482c69bfb56ab627d862da31585612ac203b", + "example_hash": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", + "test_hash": "0fa3887c7a4e2c3f051ce719117b8f07444da419b35363b9dff4a2b5ae0f17e9", + "test_files": { + "test_preprocess_main.py": "0fa3887c7a4e2c3f051ce719117b8f07444da419b35363b9dff4a2b5ae0f17e9", + "test_preprocess_main_pdd_tags.py": "abddfe41c460aa7dcd4186028134deb4eef0a85419a7f6f59869a274c25f7ee8" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/preprocess_example.py": "e7082a4a9ef830048ff32ed774a3e74da1cf4662a22115e6bd5543e1b9cdbf43", + "context/xml_tagger_example.py": "3b4606a0ac11cb728a5aa657d457312c83f2d710f53f4ac94d35675f7e911f60" + } +} \ No newline at end of file diff --git a/.pdd/meta/preprocess_python.json b/.pdd/meta/preprocess_python.json index c42350e3c5..9d193b384b 100644 --- a/.pdd/meta/preprocess_python.json +++ b/.pdd/meta/preprocess_python.json @@ -1,9 +1,9 @@ { - "pdd_version": "0.0.270.dev0", - "timestamp": "2026-06-10T22:02:58.234695+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.433752+00:00", "command": "fix", - "prompt_hash": "5ae17e5a4d901ef324d56e2c7c221863cf1ad68b6081b1e7b8d0225df3f9015c", - "code_hash": "edb9bc460d68b854c6b832ddd1c3ce42cc60e71526dade63aea1ae6a132d2259", + "prompt_hash": "029c02ce24a5e0329cd238fc79050d04b8e9eb5ecf030d0c23def59078c941f2", + "code_hash": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56", "example_hash": "e7082a4a9ef830048ff32ed774a3e74da1cf4662a22115e6bd5543e1b9cdbf43", "test_hash": "ec9a69c157443c17d8cdece1e5102252f31b470d9107efea66d89cfa977d9d13", "test_files": { @@ -16,7 +16,7 @@ "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/auto_include_example.py": "0c278ed716298149777bc7082827eb8aa6d80dac264c66b6cded6871232f2df7", "context/path_resolution_example.py": "15ba84fd11c61af8fa12dcb19d63d42f0cb09b747542bf20e69650b8ff4ac137", - "pdd/content_selector.py": "0e4fe56b42ea98d8cbf3c59f0f25849adbad5068db2f5835e5b2e7c4c21e46d2", - "pdd/include_query_extractor.py": "c2bea7ea18bb8d743394485938240089f980ca3df94b3c62f29c606ff76da453" + "pdd/content_selector.py": "c18d5f9ce0903169445ee17d2e408b88ad91a931e710e783f7c9c7cc3f2ec4af", + "pdd/include_query_extractor.py": "fa95489a0b7b8f3ad6e887844fe14f38350e56b3d2fc2e4add08318334bcd191" } -} +} \ No newline at end of file diff --git a/.pdd/meta/process_csv_change_python.json b/.pdd/meta/process_csv_change_python.json new file mode 100644 index 0000000000..f951f4cad4 --- /dev/null +++ b/.pdd/meta/process_csv_change_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.434455+00:00", + "command": "fix", + "prompt_hash": "51fda08db3c4bb80bab1047527095d28167707c6e0599c6e349064de59d604f5", + "code_hash": "0827d5c0585403e3c5f7c75c2fc07f5e9d5f635faf9159cc4b4182565308cd55", + "example_hash": "c7cf31cd55d5312b5398d3d518eddd33354fa184d0e92c6cf926a3c71d018227", + "test_hash": "9dda43c68ce5e530860175e3fc21128f9288364ffdbe0b387570185f1d144d10", + "test_files": { + "test_process_csv_change.py": "9dda43c68ce5e530860175e3fc21128f9288364ffdbe0b387570185f1d144d10" + }, + "include_deps": { + "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/prompt_lint_python.json b/.pdd/meta/prompt_lint_python.json index 303d1c7302..9457c54fbc 100644 --- a/.pdd/meta/prompt_lint_python.json +++ b/.pdd/meta/prompt_lint_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.251.dev112", - "timestamp": "2026-05-27T04:45:33.058394+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.434976+00:00", "command": "test", "prompt_hash": "ad547c4d37d4860acab5d4dfac46e9d4caa9182547683f64a5b5ee5caf2b9907", "code_hash": "df85f363082925c714e23be8d7b2e941d62a8542a3370a2581d16780cef1474e", diff --git a/.pdd/meta/prompt_repair_python.json b/.pdd/meta/prompt_repair_python.json new file mode 100644 index 0000000000..7af70df1d9 --- /dev/null +++ b/.pdd/meta/prompt_repair_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.436108+00:00", + "command": "fix", + "prompt_hash": "7534fda4f31eaa0a65b13f01ad13ff704e3976d4a6ce7463320a9b51e293728b", + "code_hash": "3bb7949b5d27a078b93f2ec872b9af53b1265dcd2740780b128b527a1cf3346d", + "example_hash": null, + "test_hash": "f5cf48e8ee5aea58108f422cc6127e21b9736b79f5dcef3d1464eb557bceb72f", + "test_files": { + "test_prompt_repair.py": "f5cf48e8ee5aea58108f422cc6127e21b9736b79f5dcef3d1464eb557bceb72f" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/change.py": "d66d22f9ef9e6a80574d91b115bf72aac534d238dd8a8085d5744e1a8c1562a3", + "pdd/checkup_prompt_main.py": "538367ba6b7fa74d9f86ba6d1235219598f7a124c58cf00ad0abf6cf027526dc", + "pdd/prompt_lint.py": "df85f363082925c714e23be8d7b2e941d62a8542a3370a2581d16780cef1474e", + "pdd/server/token_counter.py": "847ac13e3804c451aca64652877940c06b72c2fc33edc00232f1d4aa16c957e8" + } +} \ No newline at end of file diff --git a/.pdd/meta/prompt_tester_python.json b/.pdd/meta/prompt_tester_python.json new file mode 100644 index 0000000000..96dd0b296c --- /dev/null +++ b/.pdd/meta/prompt_tester_python.json @@ -0,0 +1,14 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.436650+00:00", + "command": "fix", + "prompt_hash": "db8cacbb67c5c5e4cd986133e3a0b53d93944dae1488f15cf9deb317bcc6a3af", + "code_hash": "77fb98a82eee4a2fd8d5f95091c1a1676b270507431503dd35b90c538a279025", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec" + } +} \ No newline at end of file diff --git a/.pdd/meta/provider_manager_python.json b/.pdd/meta/provider_manager_python.json index f51164f22e..64fdb9bdf2 100644 --- a/.pdd/meta/provider_manager_python.json +++ b/.pdd/meta/provider_manager_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.263.dev0", - "timestamp": "2026-06-04T20:30:11.998649+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.437080+00:00", "command": "test", - "prompt_hash": "11c78955a7665810d69fc06f4d706e7c8f48e2ed980141effb747aed9d02289f", - "code_hash": "130d9e1813d8fa98baccd63ef6bc01177722a2c39d383f881e37ffede71ed594", + "prompt_hash": "47b3f7a1cdecac48fa42942e640be85b68a40908bbb2c4cacab726cedc20c689", + "code_hash": "4003ea5149d472ca4c0b04ee456c43619ca3286b89e450aaf28ca1342bef62fc", "example_hash": "cc2bbe6cefff4ad24af4365b0c4bc2c99e672f825d12edaca7307de9c04ecfb8", - "test_hash": "6e297ca99057e4895a24e0e0a5a9469d646eff5a7ebe712d1885223fc52cd1ef", + "test_hash": "dbc8d81a2b1e01dd446fb45911e5081d65c57b1c9ee9a1ffb35a49c0a982cd38", "test_files": { - "test_provider_manager.py": "6e297ca99057e4895a24e0e0a5a9469d646eff5a7ebe712d1885223fc52cd1ef" + "test_provider_manager.py": "dbc8d81a2b1e01dd446fb45911e5081d65c57b1c9ee9a1ffb35a49c0a982cd38" }, "include_deps": {} } \ No newline at end of file diff --git a/.pdd/meta/pytest_output_python.json b/.pdd/meta/pytest_output_python.json new file mode 100644 index 0000000000..78661c3323 --- /dev/null +++ b/.pdd/meta/pytest_output_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.437588+00:00", + "command": "fix", + "prompt_hash": "2a42925af61c91af5d4c42843b6afe93f68fb8a35b5cee77a8a290f73c269315", + "code_hash": "652a27dd1e08769611abe3cb6a83f372c450279d6bf1b676741b9b7186665975", + "example_hash": "6f0cd68e3c4440081267c716651caec4fbdd7d9c4516f967517f02ae2a853920", + "test_hash": "5845761aa11bc7d4601a0e1d1b756a3c1977ae57a7d99e63b15fa70097eeab0c", + "test_files": { + "test_pytest_output.py": "5845761aa11bc7d4601a0e1d1b756a3c1977ae57a7d99e63b15fa70097eeab0c" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/pytest_slicer_python.json b/.pdd/meta/pytest_slicer_python.json new file mode 100644 index 0000000000..e56b727734 --- /dev/null +++ b/.pdd/meta/pytest_slicer_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.438052+00:00", + "command": "fix", + "prompt_hash": "2eab3431bb3a44fa472f1f28d490d5841b4c298069b73081f47b4a4336a66fa0", + "code_hash": "c02a5488fe6f7248ed387636d5824cb2f1876544d3991e43ef253648a36e49a2", + "example_hash": "c6b81f2c94831b454b37bfd7080b36f4d97a35b26083a4836276437d8f58e7e6", + "test_hash": "cb1ee4708a4471cbc2696b6f2f4a590493fa0c217c02bd1108ae18fde889b382", + "test_files": { + "test_pytest_slicer.py": "cb1ee4708a4471cbc2696b6f2f4a590493fa0c217c02bd1108ae18fde889b382" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/python_env_detector_python.json b/.pdd/meta/python_env_detector_python.json new file mode 100644 index 0000000000..404e93ac2c --- /dev/null +++ b/.pdd/meta/python_env_detector_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.438456+00:00", + "command": "fix", + "prompt_hash": "87662b4bec6070ff94de5f45f5fa821b98bd352514b4a5bd1c204961048799ab", + "code_hash": "cbe4044a83cd88a683f36d6ecfca245fef6a03ea2abc7f5c407636fccc051f35", + "example_hash": "65619b3e8bad0509f1ccf54d81b5c3760f423b6fc1925c932fc7968da78a172e", + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/reasoning_python.json b/.pdd/meta/reasoning_python.json new file mode 100644 index 0000000000..43e63e423d --- /dev/null +++ b/.pdd/meta/reasoning_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.438758+00:00", + "command": "fix", + "prompt_hash": "8c85242e5ca00f29a3f6d2dc47702a15a317dd6dfa303609f70e9555cfdf4722", + "code_hash": "b75e2beac078d86bcbee0ceb2a44cd19b4fab7a456890eead6510cd2823efa39", + "example_hash": null, + "test_hash": "43dde127047a91029a799f07efbec37256f60ec3a7b0f81b701c5d5fc17eac04", + "test_files": { + "test_reasoning.py": "43dde127047a91029a799f07efbec37256f60ec3a7b0f81b701c5d5fc17eac04" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/remote_session_python.json b/.pdd/meta/remote_session_python.json new file mode 100644 index 0000000000..c2b66fbcce --- /dev/null +++ b/.pdd/meta/remote_session_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.439844+00:00", + "command": "fix", + "prompt_hash": "9a49cada503bed5d892ea7b68570c6357b6ee220a2f5a41ba1e37204f61e6760", + "code_hash": "163292e0200246767f685e9478c8ab4531c06ba471be4ceb9a6ee8065b1cfc12", + "example_hash": "ebcf3626cc73386164ac48e804e2e7973cb9783892ac88cda49779cf158389c5", + "test_hash": "3beca26794e2f665a1052ba5dfa8a54bd90c4587c02c9c2fa03c7b85d1725e39", + "test_files": { + "test_remote_session.py": "3beca26794e2f665a1052ba5dfa8a54bd90c4587c02c9c2fa03c7b85d1725e39" + }, + "include_deps": { + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/cloud_example.py": "92418beb7a1e7f25682bf2abce5b19013b95e7eed95256c930b83c1dd6dbfb0a", + "context/get_jwt_token_example.py": "76a87c8257cb1f4cfdc2edff6225c752432afb3a5e352fcb016d08d8eae16e01", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/render_mermaid_python.json b/.pdd/meta/render_mermaid_python.json new file mode 100644 index 0000000000..4f111997ca --- /dev/null +++ b/.pdd/meta/render_mermaid_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.440204+00:00", + "command": "fix", + "prompt_hash": "42ea0f2c0870cd0542cdc8804b0ab3814e6e6e811382f31fbc7f8e692413bf0b", + "code_hash": "54ab32f4a65722fd22a49efde8529c413812ee30240b52f68515b94a8032ad57", + "example_hash": "193a57bc4191595f252881c016ba7168c27c27c01ff192128d98cf76ce5f842b", + "test_hash": "2bec83d7c4771c2c1833eb63ff31d3de1d1d3adf9d24fec0026179f56391c643", + "test_files": { + "test_render_mermaid.py": "2bec83d7c4771c2c1833eb63ff31d3de1d1d3adf9d24fec0026179f56391c643" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/resolved_sync_unit_python.json b/.pdd/meta/resolved_sync_unit_python.json new file mode 100644 index 0000000000..b1ffe5b9ef --- /dev/null +++ b/.pdd/meta/resolved_sync_unit_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.440646+00:00", + "command": "fix", + "prompt_hash": "22b41b5041d1747474bb7d1410d0a72393fbd104ac169097e8d8d4f4ea22d9b3", + "code_hash": "2ef910bdcf6f4aece8ec9440c554d3775e7ca848ee8e5b8150e4d08960fe347b", + "example_hash": null, + "test_hash": "183be24862b44bb809a0f2b234f8c912bca2447620807d353d31cd535975eb7e", + "test_files": { + "test_resolved_sync_unit.py": "183be24862b44bb809a0f2b234f8c912bca2447620807d353d31cd535975eb7e" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/routing_policy_python.json b/.pdd/meta/routing_policy_python.json new file mode 100644 index 0000000000..4eb1f7f551 --- /dev/null +++ b/.pdd/meta/routing_policy_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.441522+00:00", + "command": "fix", + "prompt_hash": "98fd165a7e3e936568815cff0b127c2504af6be42780b2e9c56a49bea3fd257d", + "code_hash": "3337699ac936552fa0e6d143fc70f6a0183edbbcbc73b1177922f3d8207dab56", + "example_hash": null, + "test_hash": "57fc855ee1f1b1bd6519e8d90495935cbe4b6cbfdc36e40040c2ce222df35532", + "test_files": { + "test_routing_policy.py": "57fc855ee1f1b1bd6519e8d90495935cbe4b6cbfdc36e40040c2ce222df35532" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/data/deepswe_manifest.json": "8d1f4d658bc01cd579c0d367e4906244d9e143f54033dd694fa403ef7ed13eea", + "pdd/gate_policy.py": "110ad068b2e5f1d4c0aa0e8ace3c8da8acb05d48f3116b6229459ed258d69667", + "pdd/reasoning.py": "b75e2beac078d86bcbee0ceb2a44cd19b4fab7a456890eead6510cd2823efa39" + } +} \ No newline at end of file diff --git a/.pdd/meta/run_generated_python.json b/.pdd/meta/run_generated_python.json new file mode 100644 index 0000000000..b18277ec79 --- /dev/null +++ b/.pdd/meta/run_generated_python.json @@ -0,0 +1,11 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.441766+00:00", + "command": "fix", + "prompt_hash": "96731fed482942f0acaaf72323a8b588499f8beafab4c6fa739236b1bd941221", + "code_hash": "96731fed482942f0acaaf72323a8b588499f8beafab4c6fa739236b1bd941221", + "example_hash": null, + "test_hash": null, + "test_files": {}, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/server_app_python.json b/.pdd/meta/server_app_python.json new file mode 100644 index 0000000000..69bc295ba2 --- /dev/null +++ b/.pdd/meta/server_app_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.442755+00:00", + "command": "fix", + "prompt_hash": "4c5bfabf92ab16c46596507eb86161fc85295e660f90b3120a1e19b95f9e8059", + "code_hash": "28394e19c9174f44cda9cf37b93229d74012bd2e61c49e0d03e665796be94279", + "example_hash": "554bb0307f2f7a0dc79ef86f8a4fd42e5017225d0c56379ad99d2939f3c1087a", + "test_hash": "3e5be61ccaf4a5ba709fc6429e029972e25548a7859b28c5712042856484806f", + "test_files": { + "test_app.py": "3e5be61ccaf4a5ba709fc6429e029972e25548a7859b28c5712042856484806f" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/server/jobs_example.py": "7694bd486d012fd9d52543c5f79a289f61dac3ed0f8c94c2ea9fd25ed6333f12", + "context/server/models_example.py": "223a832718e72ca6640728e4bd700da58edb89667931085d7d949774d8fbc228", + "context/server/security_example.py": "dc4f3dc06455ba6180f4536aa67ce4e9a5efd52e0e9cd7702c3f2ec6ef96aac9" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_click_executor_python.json b/.pdd/meta/server_click_executor_python.json new file mode 100644 index 0000000000..9b46b7c23a --- /dev/null +++ b/.pdd/meta/server_click_executor_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.443262+00:00", + "command": "fix", + "prompt_hash": "d82aceff435ce2a46ef2f4297f06393f559254168774ef122d905417a8b3ed0d", + "code_hash": "b8e1e120d050f0545f2c3979c94390b07431a30af391bfd30bc052770f11edda", + "example_hash": "a61ee766f5b09bfa0de58533125b85d8855186f17f3109101887177a87d8d5c9", + "test_hash": "b07719b4afb26baeff40c15d2e69ecd7b2d7575f4871ab07ea99afc6d64dc640", + "test_files": { + "test_click_executor.py": "b07719b4afb26baeff40c15d2e69ecd7b2d7575f4871ab07ea99afc6d64dc640" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_executor_python.json b/.pdd/meta/server_executor_python.json new file mode 100644 index 0000000000..8ea1b8852c --- /dev/null +++ b/.pdd/meta/server_executor_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.444087+00:00", + "command": "fix", + "prompt_hash": "77f3e901f05b202431961276e304ea0327345a69924dff2caf8ab5322ee9e95f", + "code_hash": "7b4662572a02d650c81af625290ecbd7e1823bb3d4247326d726f9ba95fc511c", + "example_hash": "fb5d8d40aeeb2bf401dc6a84a43bee6936ee1e734b2b00bd08e7fbc44219a9cf", + "test_hash": "455266ddce3a40b351c4d1e56cb2b9a0afc23cac6a70bbae84f92f0ecf715684", + "test_files": { + "test_executor.py": "455266ddce3a40b351c4d1e56cb2b9a0afc23cac6a70bbae84f92f0ecf715684" + }, + "include_deps": { + "context/click_executor_example.py": "322d322bcbe2672e9adb1d52744018f38ae6ae3209711441816f923727760b8e", + "context/core/cli_example.py": "bbc8ef9798628f6ed733c17b3863585b3724cd08c7e09ace0049c13fc157abb2", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_jobs_python.json b/.pdd/meta/server_jobs_python.json index cfe8bd735a..d1056314f7 100644 --- a/.pdd/meta/server_jobs_python.json +++ b/.pdd/meta/server_jobs_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.231", - "timestamp": "2026-05-08T21:23:44.571476+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.444909+00:00", "command": "fix", - "prompt_hash": "0e9e0e584f70825743a2ff11ea0d73cdc43df6030ef9707b385fb23475348f61", + "prompt_hash": "c79d067d505a37c8d69ffb22ca520baa6ab385be61cd489b9e63627393585dd1", "code_hash": "975aa1aaab1500f7ad8e0dfe667842fb43a5b44e045ebd4e2a7cd177aa0af3e7", "example_hash": "7694bd486d012fd9d52543c5f79a289f61dac3ed0f8c94c2ea9fd25ed6333f12", "test_hash": "0027ff985ee28e4f4cc9823f793f737c3b1b6e9cb7a526a58f2d7fa6f42945e5", @@ -10,7 +10,7 @@ "test_jobs.py": "0027ff985ee28e4f4cc9823f793f737c3b1b6e9cb7a526a58f2d7fa6f42945e5" }, "include_deps": { - "context/python_preamble.prompt": "57a3e51f529024ec0cb9658cd6ac61a7c8051ba0c8e887b31cf00b2e78a07d83", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/server/jobs_example.py": "7694bd486d012fd9d52543c5f79a289f61dac3ed0f8c94c2ea9fd25ed6333f12", "context/server/models_example.py": "223a832718e72ca6640728e4bd700da58edb89667931085d7d949774d8fbc228" } diff --git a/.pdd/meta/server_models_python.json b/.pdd/meta/server_models_python.json new file mode 100644 index 0000000000..22ee9514b7 --- /dev/null +++ b/.pdd/meta/server_models_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.445799+00:00", + "command": "fix", + "prompt_hash": "afa81609237d8c779745c0e4d660247233d9f7626443976f6efa300e80e6744e", + "code_hash": "a17b2f09033b2fe7063f484a2efb59184f7cb2fba822ee25605a93bbe5905941", + "example_hash": "223a832718e72ca6640728e4bd700da58edb89667931085d7d949774d8fbc228", + "test_hash": "df4d2f5cebc4b26915c7120e12f4168d71741c59eda7dd29202c141c9aabac8d", + "test_files": { + "test_models.py": "df4d2f5cebc4b26915c7120e12f4168d71741c59eda7dd29202c141c9aabac8d" + }, + "include_deps": { + "context/fastapi_example.py": "4b3d64175b8f46b48a4387e9cf98ed4024fd74a57413bd2f8a55c5d9c3dd0108", + "context/job_manager_example.py": "e421698fdf16c5dfebf97eb3f2cb7210878efa1869804f871100489e35102543", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/websocket_example.py": "6f50399fd41177e47da3f170a1cc84380f8f266036e8f510f7807a916265ab0f" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_architecture_python.json b/.pdd/meta/server_routes_architecture_python.json new file mode 100644 index 0000000000..46e5d025fd --- /dev/null +++ b/.pdd/meta/server_routes_architecture_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.446702+00:00", + "command": "fix", + "prompt_hash": "a768e3fc89c1c6f5aa261492547c841a9239893662727f682404d6b749752d37", + "code_hash": "67df73835b6282fde848c0ab558f3fa18c108b2b27b20aec8cf23f2f1a291446", + "example_hash": "6adddc3703c575ef7eaa12c58df0067e438c2fe328e5037fb69856595e862bf8", + "test_hash": "46e1daefed9b370ac235b49d9ec762bf27f945d37d31176dceb196606ed2e3fd", + "test_files": { + "test_architecture.py": "46e1daefed9b370ac235b49d9ec762bf27f945d37d31176dceb196606ed2e3fd" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/fastapi_example.py": "4b3d64175b8f46b48a4387e9cf98ed4024fd74a57413bd2f8a55c5d9c3dd0108", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_auth_python.json b/.pdd/meta/server_routes_auth_python.json new file mode 100644 index 0000000000..3fbbf4bc89 --- /dev/null +++ b/.pdd/meta/server_routes_auth_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.447479+00:00", + "command": "fix", + "prompt_hash": "c5ed12c3a857e38d8431cafd7a817c18642693b62bc746681efd7be9c5c0460f", + "code_hash": "0964f8ca62a4b95d114f8938c5afd5cf5ec480a350b7bd442fa4fc62ef200eb3", + "example_hash": "8d6c5e1e858f07440184c0ae1b7f98ffa53a57233031513fa6566131404ceab5", + "test_hash": "701217ca61602e22b3dfe34efce69d732857292b5ee21057b65a474627e682d3", + "test_files": { + "test_auth.py": "701217ca61602e22b3dfe34efce69d732857292b5ee21057b65a474627e682d3" + }, + "include_deps": { + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/get_jwt_token_example.py": "76a87c8257cb1f4cfdc2edff6225c752432afb3a5e352fcb016d08d8eae16e01", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_commands_python.json b/.pdd/meta/server_routes_commands_python.json new file mode 100644 index 0000000000..53576def67 --- /dev/null +++ b/.pdd/meta/server_routes_commands_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.448562+00:00", + "command": "fix", + "prompt_hash": "924811be56ddaf51635685a42a7a4019dd92d77486051d5e1e800bcdcf268b08", + "code_hash": "aaa1af05971354a74e545756b347fe1f718875bd71d12c4bd51962ad084e0fe4", + "example_hash": "2aee960b3f00528d1da6cd878806b82a9ea703827d66a8618d1899d6ea9076ea", + "test_hash": "a60d4df0560867a7cbab7edb3526fc4f5da7fb81cfa5ada9c925a029f7155f2c", + "test_files": { + "test_commands.py": "a60d4df0560867a7cbab7edb3526fc4f5da7fb81cfa5ada9c925a029f7155f2c" + }, + "include_deps": { + "context/cli_example.py": "b2205688a0e74867c4e108ef97770861d2ecf21419d9f3e10991acbeb8c4235a", + "context/fastapi_example.py": "4b3d64175b8f46b48a4387e9cf98ed4024fd74a57413bd2f8a55c5d9c3dd0108", + "context/job_manager_example.py": "e421698fdf16c5dfebf97eb3f2cb7210878efa1869804f871100489e35102543", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/server/models_example.py": "223a832718e72ca6640728e4bd700da58edb89667931085d7d949774d8fbc228" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_config_python.json b/.pdd/meta/server_routes_config_python.json new file mode 100644 index 0000000000..2e75505b32 --- /dev/null +++ b/.pdd/meta/server_routes_config_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.449296+00:00", + "command": "fix", + "prompt_hash": "7ba89c5ce719f92cc6c9e281f1c94bf2594dd4f0e0229ae9cf75431e2787b11c", + "code_hash": "efe80f308a6a2acdb6a207288f746d39f0947da597c44c358595ff7b70e587d9", + "example_hash": "58f2b27cdf85200a52fbe76324d02431dc62f339afd3896de37c0fe759f55cde", + "test_hash": "d56946a2922b543bd87bdf3f124e24b648a374676463f7e695aa6ef1b994290f", + "test_files": { + "test_config.py": "d56946a2922b543bd87bdf3f124e24b648a374676463f7e695aa6ef1b994290f" + }, + "include_deps": { + "context/cloud_example.py": "92418beb7a1e7f25682bf2abce5b19013b95e7eed95256c930b83c1dd6dbfb0a", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/server/routes/config_example.py": "58f2b27cdf85200a52fbe76324d02431dc62f339afd3896de37c0fe759f55cde" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_extracts_python.json b/.pdd/meta/server_routes_extracts_python.json new file mode 100644 index 0000000000..7418cb7219 --- /dev/null +++ b/.pdd/meta/server_routes_extracts_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.450292+00:00", + "command": "fix", + "prompt_hash": "3ee950acac8a66d9aa2331c30049a7f91935f73b3a9753534e89d98e133a6adc", + "code_hash": "1308d4b7c79d5560e31d25c60820405c1e5f3ef2560eb03674f0fb4e9cf03794", + "example_hash": "41070c16e3eca0acdf3b0877a08143df0d48b3fbd06db022fb7e1e883574688e", + "test_hash": "74e98e152be97fcc0658530f189051ba2d1e74386bf0cb358cdfbb355c5bba69", + "test_files": { + "test_extracts.py": "74e98e152be97fcc0658530f189051ba2d1e74386bf0cb358cdfbb355c5bba69" + }, + "include_deps": { + "context/extracts_prune_example.py": "b8a894f24d715f42be14b9977b6c091e75401e3f46f0722703fa63b61b26a7ee", + "context/fastapi_example.py": "4b3d64175b8f46b48a4387e9cf98ed4024fd74a57413bd2f8a55c5d9c3dd0108", + "context/include_query_extractor_example.py": "83c8b945de75bd49b258f4feabbdda3d9c08a06ad9afca3e90df7534f68a34aa", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_files_python.json b/.pdd/meta/server_routes_files_python.json new file mode 100644 index 0000000000..9f02a0104e --- /dev/null +++ b/.pdd/meta/server_routes_files_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.451268+00:00", + "command": "fix", + "prompt_hash": "33d6cabb10340b8fae1ab7b0ebe3439b0aff13aacffb9d1f1f837446a92be95c", + "code_hash": "966d3704d46b38d3448cad3b9f3b748b61e8b572c4281f6cc063da105e56d290", + "example_hash": "9e5d8e77e1d0238394c331a872fcb31e4597100fc9427d8bba7ee3550df4323d", + "test_hash": "e4b391cc756c8e86adeb7a9a43bb60a735b2063c24c88792243afe8b91595a16", + "test_files": { + "test_files.py": "e4b391cc756c8e86adeb7a9a43bb60a735b2063c24c88792243afe8b91595a16" + }, + "include_deps": { + "context/fastapi_example.py": "4b3d64175b8f46b48a4387e9cf98ed4024fd74a57413bd2f8a55c5d9c3dd0108", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/server/models_example.py": "223a832718e72ca6640728e4bd700da58edb89667931085d7d949774d8fbc228", + "context/server/security_example.py": "dc4f3dc06455ba6180f4536aa67ce4e9a5efd52e0e9cd7702c3f2ec6ef96aac9" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_prompts_python.json b/.pdd/meta/server_routes_prompts_python.json new file mode 100644 index 0000000000..e3f058fad0 --- /dev/null +++ b/.pdd/meta/server_routes_prompts_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.452786+00:00", + "command": "fix", + "prompt_hash": "5a129d5e7110839ed03cde6337526e04fd63eec16ab5e6385e999f28ab589f4b", + "code_hash": "b49c7a2072243f6d1b3bbe762e1f023d890fbbdccf4c57f882df3de04f7a971f", + "example_hash": "0c143874f91ca038a84580bd829fccf6adbe8bedfd33517089cc2bee6b7a04e1", + "test_hash": "7096ca56eb33b8d62a18e3327eac88fdaa702b7b205e22a8a946273c840fcd66", + "test_files": { + "test_prompts.py": "7096ca56eb33b8d62a18e3327eac88fdaa702b7b205e22a8a946273c840fcd66" + }, + "include_deps": { + "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/fastapi_example.py": "4b3d64175b8f46b48a4387e9cf98ed4024fd74a57413bd2f8a55c5d9c3dd0108", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/server/security_example.py": "dc4f3dc06455ba6180f4536aa67ce4e9a5efd52e0e9cd7702c3f2ec6ef96aac9", + "context/sync_determine_operation_example.py": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_routes_websocket_python.json b/.pdd/meta/server_routes_websocket_python.json new file mode 100644 index 0000000000..b26f3ad1f2 --- /dev/null +++ b/.pdd/meta/server_routes_websocket_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.453605+00:00", + "command": "fix", + "prompt_hash": "95bf0f052dbb0161c69f356bae8d9cc273dce51db1729e520f87fa48fa40c583", + "code_hash": "961fbae5ff5944b4be4104be65320c8bfb3bda62bff4db6eeaf4df8b1da1039a", + "example_hash": "a4c2313449f3174039edf4ab1f2030247b4da0eb31e6411b1008516be95eb3cf", + "test_hash": "d6167bdd4e173c9a3f00555361206d57130d280419edc1f051cbb8608acb8405", + "test_files": { + "test_websocket.py": "d6167bdd4e173c9a3f00555361206d57130d280419edc1f051cbb8608acb8405" + }, + "include_deps": { + "context/job_manager_example.py": "e421698fdf16c5dfebf97eb3f2cb7210878efa1869804f871100489e35102543", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/server/models_example.py": "223a832718e72ca6640728e4bd700da58edb89667931085d7d949774d8fbc228" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_security_python.json b/.pdd/meta/server_security_python.json new file mode 100644 index 0000000000..f97c43c858 --- /dev/null +++ b/.pdd/meta/server_security_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.454086+00:00", + "command": "fix", + "prompt_hash": "e54788c440ea949be62bfd1ce223d9fdb605884254981500234d3d2967e6d2c6", + "code_hash": "1eeb395579f49c24ce7a6b695438e74f738af2dac604384bf8e2105c3d6cf4e7", + "example_hash": "dc4f3dc06455ba6180f4536aa67ce4e9a5efd52e0e9cd7702c3f2ec6ef96aac9", + "test_hash": "db19cd096ac28c9be920565d84cb9c4a8b9ccc4b8eee2331d92477316483be83", + "test_files": { + "test_security.py": "db19cd096ac28c9be920565d84cb9c4a8b9ccc4b8eee2331d92477316483be83" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_terminal_spawner_python.json b/.pdd/meta/server_terminal_spawner_python.json new file mode 100644 index 0000000000..8c5d83efd6 --- /dev/null +++ b/.pdd/meta/server_terminal_spawner_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.454564+00:00", + "command": "fix", + "prompt_hash": "c6238db322a2907172a42f470c7a345b8e4703692c1240e522c3e4c8d553a07b", + "code_hash": "efffd485569bb2f2e673b408c607a02a9b3325f46d2db8af2f4f8f8439f49fb5", + "example_hash": "de89761e9228d058064a52ed3bf4d84f2ceba1991e5b8e0a45a4af8f0c477e19", + "test_hash": "4cea9f3187218738c94ec6f09ae1c131d7fdef426dd4da6c495231e7e3163e42", + "test_files": { + "test_terminal_spawner.py": "4cea9f3187218738c94ec6f09ae1c131d7fdef426dd4da6c495231e7e3163e42" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/server_token_counter_python.json b/.pdd/meta/server_token_counter_python.json new file mode 100644 index 0000000000..48b78044e9 --- /dev/null +++ b/.pdd/meta/server_token_counter_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.455051+00:00", + "command": "fix", + "prompt_hash": "2487fd62e2c8a29e5a404d43df9f63df63eabae82b7e6bbdab9804df9fa8be18", + "code_hash": "847ac13e3804c451aca64652877940c06b72c2fc33edc00232f1d4aa16c957e8", + "example_hash": "75a40b397db75482e743fc7ec0ec26ae09650746111abb48a941e8d58214c9a5", + "test_hash": "f661f43b95b469139c1c46b8e0091a7fdf81a993ff73ab5331f8c13c8f6a1984", + "test_files": { + "test_token_counter.py": "f661f43b95b469139c1c46b8e0091a7fdf81a993ff73ab5331f8c13c8f6a1984" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/setup_tool_python.json b/.pdd/meta/setup_tool_python.json new file mode 100644 index 0000000000..40cd8220be --- /dev/null +++ b/.pdd/meta/setup_tool_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.456247+00:00", + "command": "fix", + "prompt_hash": "ce35b42282c1f64f3c38653035d643e945e8b88a7ee291955b6620fb3e065176", + "code_hash": "8d2c78cd67bea21d2637669586eaa49608de0b0d6a5e1d36d6ddb9554e968baa", + "example_hash": "be376935a57f642e65ac1e938c2dec8e7b8dd66348164eaac648fcf4864e3b59", + "test_hash": "7447aae2c91e9706330b183766fe95ebe5d33e24b9f8f235dc9fe8d9e1b6b405", + "test_files": { + "test_setup_tool.py": "7447aae2c91e9706330b183766fe95ebe5d33e24b9f8f235dc9fe8d9e1b6b405" + }, + "include_deps": { + "context/cli_detector_example.py": "db64a53121864c633ba1586f1af491ae7cc617c10cf4c477a7e6d262f676cd23", + "context/model_tester_example.py": "9d33f093cdac4c100bf671e891a68c7f83e2e09e74cd65f6b53cb567d77d3cd0", + "context/pddrc_initializer_example.py": "3ba502fa9e2a2f438aaa890f0b654a98e5b8665253e10446acafda90f7eedad9", + "context/provider_manager_example.py": "cc2bbe6cefff4ad24af4365b0c4bc2c99e672f825d12edaca7307de9c04ecfb8" + } +} \ No newline at end of file diff --git a/.pdd/meta/split_main_python.json b/.pdd/meta/split_main_python.json new file mode 100644 index 0000000000..06f2e278c5 --- /dev/null +++ b/.pdd/meta/split_main_python.json @@ -0,0 +1,20 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.457962+00:00", + "command": "fix", + "prompt_hash": "f99f201197b89ba0fac4883806e66b289fd9066a132d282d8e90b79ed65d9717", + "code_hash": "381837b939069c6fef6c115caaefaa34c3103722de6ca95037ced13941edae75", + "example_hash": "ced192fcbfbfda15b35bd2dad5bbf4b4888acb091084cf58326832d224a77661", + "test_hash": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887", + "test_files": { + "test_split_main.py": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/split_example.py": "c36a6c3e5ddac660ef95d72dabc89f5453a3ebcd47f5f82ddc5fec77806154d9", + "pdd/validate_prompt_includes.py": "fa97b72a58534e255768634f928f4cfdd2130a7a4d8b296da3eefdf77d47855b" + } +} \ No newline at end of file diff --git a/.pdd/meta/split_python.json b/.pdd/meta/split_python.json new file mode 100644 index 0000000000..d8ea293882 --- /dev/null +++ b/.pdd/meta/split_python.json @@ -0,0 +1,22 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.459639+00:00", + "command": "fix", + "prompt_hash": "b3d22d3a857a401b3e28f39864bef2a8bad98b59f0e2046731c878eae8a5b1a1", + "code_hash": "45894f5de8eb4f172b375f50858f89476bc39ab25bd1c6f0cf45dbb29f884b1e", + "example_hash": "c36a6c3e5ddac660ef95d72dabc89f5453a3ebcd47f5f82ddc5fec77806154d9", + "test_hash": "c0689f1b51cdf02e68d03f22a21828301701ab59c92fbf1ec9bad382ae8461c2", + "test_files": { + "test_split.py": "c0689f1b51cdf02e68d03f22a21828301701ab59c92fbf1ec9bad382ae8461c2", + "test_split_main.py": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887", + "test_split_seam_resolution.py": "bce4215346ba2c4c22da9cd22313889df1229c6df8f66ffa1f561fa031f1233f", + "test_split_validation.py": "38159d3460e22b00859f413a841dbc515563bbeaf6c8e1c5b8671f9ba5a6ec98" + }, + "include_deps": { + "context/change/13/initial_split.py": "61247194419b17b8cd986efdbbbb6782a34e89b3cfe6e895ce24419490b33578", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/split_validation_python.json b/.pdd/meta/split_validation_python.json new file mode 100644 index 0000000000..cbb00b650a --- /dev/null +++ b/.pdd/meta/split_validation_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.460460+00:00", + "command": "fix", + "prompt_hash": "ac0c920040e138d26877842ef7e159726d5e1ed06d4811ef183449fac331eed5", + "code_hash": "e51a9512fc4cedbe362f25da3c97c23a89057901bff10c6b04eeefe77b79dafe", + "example_hash": "007c34d78c7605bb0ddfc3cb2df14095e387159b3ea746056e34cb304547a358", + "test_hash": "38159d3460e22b00859f413a841dbc515563bbeaf6c8e1c5b8671f9ba5a6ec98", + "test_files": { + "test_split_validation.py": "38159d3460e22b00859f413a841dbc515563bbeaf6c8e1c5b8671f9ba5a6ec98" + }, + "include_deps": { + "context/get_test_command_example.py": "33b16476536f8c9424d3222ffc4a5cd5ecee6ad0589b2c66a4f3c7f1e265106c", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/prompts/get_lint_commands_python.prompt": "d8c47a583973f8fd15353b01a4744b6ac7d31949beff51af7c917c9aac7736b7" + } +} \ No newline at end of file diff --git a/.pdd/meta/story_coverage_python.json b/.pdd/meta/story_coverage_python.json new file mode 100644 index 0000000000..679ff073f2 --- /dev/null +++ b/.pdd/meta/story_coverage_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.460949+00:00", + "command": "fix", + "prompt_hash": "372aa16676ec2f4f1e528dbb9c6335b24c4181c8b04123b064704f25cb9b479d", + "code_hash": "6d15872bac258806e49feda2cb37ff410d667930905eedec836192395cfd7f75", + "example_hash": "8dc2e6fea81ea2bab743ab5e22295e41eb277bc75cd553fb35278020dc4eef02", + "test_hash": "aec88c13736cd4b0dc40c841cfcd4299ce4f235294755f254d5ba0fe97ef934e", + "test_files": { + "test_story_coverage.py": "aec88c13736cd4b0dc40c841cfcd4299ce4f235294755f254d5ba0fe97ef934e" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/story_regression_gate_python.json b/.pdd/meta/story_regression_gate_python.json new file mode 100644 index 0000000000..68b834592f --- /dev/null +++ b/.pdd/meta/story_regression_gate_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.461439+00:00", + "command": "fix", + "prompt_hash": "3c3381a2d75792bdc45e201fe44dc9a1b24cca4a1162c37b1415b043df9a52a9", + "code_hash": "51d3dc49dda8a594f71816a83143b1cc14b5c01ac917d17fd9505fc3da2ea06c", + "example_hash": null, + "test_hash": "95e60df5f061c90e881fc50d89870dd86cadf109627049a9dc729d4dab74e6f3", + "test_files": { + "test_story_regression_gate.py": "95e60df5f061c90e881fc50d89870dd86cadf109627049a9dc729d4dab74e6f3" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/story_regression_python.json b/.pdd/meta/story_regression_python.json new file mode 100644 index 0000000000..4a4374315f --- /dev/null +++ b/.pdd/meta/story_regression_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.462064+00:00", + "command": "fix", + "prompt_hash": "689cbfe6e7648a9087f1f20aae4b80260ece0834c8b8673fdda254392d49bed1", + "code_hash": "7f3e89234750cf8483659ae2c409ee663d9b2b981b0689b9c9a69c6778a772d5", + "example_hash": null, + "test_hash": "919725a4142dd273cff39b3eba959ab50c18b4cde38139eb2559a1e191958bc9", + "test_files": { + "test_story_regression.py": "919725a4142dd273cff39b3eba959ab50c18b4cde38139eb2559a1e191958bc9", + "test_story_regression_gate.py": "95e60df5f061c90e881fc50d89870dd86cadf109627049a9dc729d4dab74e6f3" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/user_story_tests_example.py": "ae08c16469db958715911eeedc5916eb68fc71c90b605c4b78f6e93096873c86" + } +} \ No newline at end of file diff --git a/.pdd/meta/story_test_generator_python.json b/.pdd/meta/story_test_generator_python.json new file mode 100644 index 0000000000..60d1fe222a --- /dev/null +++ b/.pdd/meta/story_test_generator_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.462352+00:00", + "command": "fix", + "prompt_hash": "08ebc4332fc8aace6e07544ef82bba07e1a1a9eb00ee78086633d510a7c70e35", + "code_hash": "8189426246b8bc0c1cc5563b93fbca74cdd5786875f06725c7d0ad78f177a119", + "example_hash": null, + "test_hash": "6c019ddd2abcbd71e06527b5e8fc129b4511b991baf1511d70d96ff84eb73eff", + "test_files": { + "test_story_test_generator.py": "6c019ddd2abcbd71e06527b5e8fc129b4511b991baf1511d70d96ff84eb73eff" + }, + "include_deps": {} +} \ No newline at end of file diff --git a/.pdd/meta/summarize_directory_python.json b/.pdd/meta/summarize_directory_python.json index ce819c39ea..e6dabeeee4 100644 --- a/.pdd/meta/summarize_directory_python.json +++ b/.pdd/meta/summarize_directory_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.246.dev34", - "timestamp": "2026-05-21T02:39:13.009516+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.463319+00:00", "command": "update", - "prompt_hash": "d4bb457d5fbf85648e7c2222affd99928729947aa2a46936b7ae2c855bf34d80", + "prompt_hash": "693ec6464aea87ceb2babb81f138ebb328f0bc40eebfc7b8f82344033a81ea84", "code_hash": "e715f8c9f90dd9cb6b656ef83df4a09388edd97451e0706e964fe713eecf6aaf", "example_hash": "99f9b729f3b148891d471e79e5a29e67e39c30aad8e9922ced2982ca02b158ea", "test_hash": "049ed6ddc2cd8bd3915eeb79f0b87524eef136157f684cfd7453d35d0f799425", @@ -10,8 +10,8 @@ "test_summarize_directory.py": "049ed6ddc2cd8bd3915eeb79f0b87524eef136157f684cfd7453d35d0f799425" }, "include_deps": { - "context/llm_invoke_example.py": "48c5aece0ddd153f95ec8a53802d2173d4da12a920b398c5feebb307b9958417", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } -} +} \ No newline at end of file diff --git a/.pdd/meta/sync_animation_python.json b/.pdd/meta/sync_animation_python.json index c741954a75..94961f8eef 100644 --- a/.pdd/meta/sync_animation_python.json +++ b/.pdd/meta/sync_animation_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.278.dev0", - "timestamp": "2026-06-19T04:14:17.628703+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.464672+00:00", "command": "fix", - "prompt_hash": "d27f3b08a706dd32a91e67c7c4623ca47728f1b2138a8533ec25d67793568021", + "prompt_hash": "66bd02391a0239cb2977d371ceb48a7ce0bfbd7b5c801db79a88bde530e1dde3", "code_hash": "b9261a68d14049db76c89179f98ee1c45a073cc9a656607d447612e23f68e285", "example_hash": "5b6a8af940fe44241889a279c1a8d3c978fe0c6ec3afc648510d8e33ffa7b18c", "test_hash": "f76041e4a4e313d3005d5961e76c3b08bfc26549e498d341cefe31560c328ebd", @@ -13,7 +13,7 @@ "test_sync_animation_phases.py": "fa098d0dc0e6bb3f1f45863c1d01cf1a798fdcbaa3a402025aa241a39faef76c" }, "include_deps": { - "README.md": "80504ec987045c156641c781764ebbd33af20da3e8854307158fe1110fe1845b", + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", "context/logo_animation_example.py": "f32a5cc330235c3b61fb16ac62d3ae7531c7c6dbc11af077fc79054736f0944d", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/sync_determine_operation_python.json b/.pdd/meta/sync_determine_operation_python.json index 7445a7bb1d..b23f745b11 100644 --- a/.pdd/meta/sync_determine_operation_python.json +++ b/.pdd/meta/sync_determine_operation_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.296.dev0", - "timestamp": "2026-07-09T09:54:54.515165+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.467383+00:00", "command": "fix", "prompt_hash": "67066038dc835de0304bdf437277088994f8293b858343af8a8c1ba00b7c86a2", "code_hash": "e616ac746674a9f1e8be84bf3093d5e1f45ff0175bc3767b758f2d17b2c54132", diff --git a/.pdd/meta/sync_main_python.json b/.pdd/meta/sync_main_python.json new file mode 100644 index 0000000000..ca9bad0e8c --- /dev/null +++ b/.pdd/meta/sync_main_python.json @@ -0,0 +1,24 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.471053+00:00", + "command": "fix", + "prompt_hash": "fcfcfdc0014299ae85bfd643bccd062a5ba57a107ae1f54be6f507303cc85a9b", + "code_hash": "68873b5f5599765e8220419ac18c9f264497f38f0e573308986a0feadda65159", + "example_hash": "9a7961a4044a54c46ce6c43c8adbbb83da46f233d9c6a9eaa28302440c0052c0", + "test_hash": "9f617d403a3ba62d0f46451bf63d81485f6fb7c4ec0a56a9b342b4c244a8d330", + "test_files": { + "test_sync_main.py": "9f617d403a3ba62d0f46451bf63d81485f6fb7c4ec0a56a9b342b4c244a8d330" + }, + "include_deps": { + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/sync_main_example.py": "9a7961a4044a54c46ce6c43c8adbbb83da46f233d9c6a9eaa28302440c0052c0", + "context/sync_orchestration_example.py": "cc1313a948946026d418c85a07e5bf0eedeb5915c44d630440e489979755e1f7", + "pdd/agentic_sync_runner.py": "572f865d1bdbddf4827d5f308eb72030c3ed085c4f570284cbda8c961d01af2d", + "pdd/code_generator_main.py": "e83cc9bd8890d032fcf63001b83feb766d632ab08d00e20110e489e0386962b4", + "pdd/compressed_sync_context.py": "661fde0fcc42ce39c1004e47a774a8fd799b789065519cb5688949c35fed4859" + } +} \ No newline at end of file diff --git a/.pdd/meta/sync_orchestration_python.json b/.pdd/meta/sync_orchestration_python.json index 5b52c7dd61..928efe35bf 100644 --- a/.pdd/meta/sync_orchestration_python.json +++ b/.pdd/meta/sync_orchestration_python.json @@ -1,31 +1,32 @@ { - "pdd_version": "0.0.234", - "timestamp": "2026-05-12T02:53:56.362536+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.476722+00:00", "command": "fix", - "prompt_hash": "b9b900ce1b0cf9e50b73c4aad750e2231f632beda3c286c0469f21c0dc3a8475", - "code_hash": "7ef19b3e7eafd7abd0f54c9de74b7c4d8be5559d84b2673f1c60cb9313d4842e", + "prompt_hash": "31fceea8fcb2e3933a156779918cce48ae3a108541b1a0d5203652cac919a22b", + "code_hash": "66b8002c0123618f6030600e5a68f74eef6c2731ef51e7b9c753f068c55dbe5d", "example_hash": "cc1313a948946026d418c85a07e5bf0eedeb5915c44d630440e489979755e1f7", - "test_hash": "3fce96bc02b851cc3e2d00001b0de3a2436f687c65a53d5e423212ac5c6d2517", + "test_hash": "7a4a23ed7c00408887d4ca9b604cb9715e0ad6e0a9c3e9e1b4df78603b396f41", "test_files": { - "test_sync_orchestration.py": "3fce96bc02b851cc3e2d00001b0de3a2436f687c65a53d5e423212ac5c6d2517" + "test_sync_orchestration.py": "7a4a23ed7c00408887d4ca9b604cb9715e0ad6e0a9c3e9e1b4df78603b396f41" }, "include_deps": { - "docs/whitepaper.md": "25b87d4af53ba35e7fa80b12f6bf09d12e16b8b952341df94cf8b47160886adf", - "README.md": "b572bb7bf64f3d9473845a45b8c942fc66b527bc516c960059bc538e574ae4bc", + "docs/whitepaper.md": "3347db03fa35376024b59d8546efdf0858655746490561b88b710fa6b85017cc", + "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", - "context/code_generator_main_example.py": "679590f0913600886d99469d8ece23fbbfe6bea2e626b0d5d2ab5fdcdc079b80", + "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", "context/context_generator_main_example.py": "77c3de786f31392540ec609d4b3942e98e996ae14c4014f5018cf2b05a560df4", "context/crash_main_example.py": "5c9b909107f74f773ccf7013d556a5812643d2a3b086e79fe07da7ea7877458c", "context/fix_main_example.py": "29f88d8bfcc2256ebebe6efcb611f9487eb5ca6d8781286a6dd98689f92bca7a", "context/fix_verification_main_example.py": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", - "context/get_run_command_example.py": "4d187e844adb255c2738274556f4828728d0d73d84ebf8bda885d51d4be9414f", "context/get_test_command_example.py": "33b16476536f8c9424d3222ffc4a5cd5ecee6ad0589b2c66a4f3c7f1e265106c", - "context/operation_log_example.py": "6cd7962ab255d6080aeb97897175250f987ce936cf7333e7601f10834405a940", - "context/pytest_output_example.py": "6f0cd68e3c4440081267c716651caec4fbdd7d9c4516f967517f02ae2a853920", + "context/operation_log_example.py": "2660def7012d9b79bad3db33cf399ac603cc1c35dff0b064cbdd2638a013de1d", "context/python_env_detector_example.py": "65619b3e8bad0509f1ccf54d81b5c3760f423b6fc1925c932fc7968da78a172e", - "context/sync_determine_operation_example.py": "94a333b37d9875bcc9b39e22d4d00de1b196ad2f7e0fa997e6f638e153dbdfad", - "context/update_main_example.py": "b318834c648f25e6141d81f3ecac1d9da592a6bb4740500983f2b07b8a10d902" + "context/sync_determine_operation_example.py": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5", + "context/update_main_example.py": "9fe01fd19196c2604c91d101e49db849e0e1c9fabafeb2ad831a9c91b2f26416", + "pdd/compressed_sync_context.py": "661fde0fcc42ce39c1004e47a774a8fd799b789065519cb5688949c35fed4859", + "pdd/get_run_command.py": "5eec778a234abc4ace4166d71a68f6e49f1b81491962867de81f61be882a5319", + "pdd/pytest_output.py": "652a27dd1e08769611abe3cb6a83f372c450279d6bf1b676741b9b7186665975" } } \ No newline at end of file diff --git a/.pdd/meta/sync_order_python.json b/.pdd/meta/sync_order_python.json new file mode 100644 index 0000000000..9cf95d75c9 --- /dev/null +++ b/.pdd/meta/sync_order_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.478137+00:00", + "command": "fix", + "prompt_hash": "427b20071b0f873b8a9db5550f040fbea6ba89a49ae58f421ceccfc545679616", + "code_hash": "6cdaed3b56d9cc12f38ee5ac93b8623899372ea2d177c4f131ec258edb94d0dd", + "example_hash": "b4eb1e167e7604c7dbac703bdcba7287188fa9d2d5ef6d490216d003cdc542fa", + "test_hash": "196505cf8e1fa198c07c118479a6847bc2b921efb8f01be98651e01f302bbf85", + "test_files": { + "test_sync_order.py": "196505cf8e1fa198c07c118479a6847bc2b921efb8f01be98651e01f302bbf85" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/auto_include_example.py": "0c278ed716298149777bc7082827eb8aa6d80dac264c66b6cded6871232f2df7", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/sync_tui_python.json b/.pdd/meta/sync_tui_python.json index 6eecff6cd9..2ec24f87ea 100644 --- a/.pdd/meta/sync_tui_python.json +++ b/.pdd/meta/sync_tui_python.json @@ -1,6 +1,6 @@ { - "pdd_version": "0.0.257.dev0", - "timestamp": "2026-06-01T18:19:03.939345+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.478680+00:00", "command": "update", "prompt_hash": "5eb3bb0151fa49a4f51f87c06051545bfa07a3bdf27718f23616a6a301deefa2", "code_hash": "941cbbd6026742784188c66b97d64479daa733ffe1ff2d3d11f464e8a0e10992", diff --git a/.pdd/meta/template_expander_python.json b/.pdd/meta/template_expander_python.json new file mode 100644 index 0000000000..890843b9c6 --- /dev/null +++ b/.pdd/meta/template_expander_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.479083+00:00", + "command": "fix", + "prompt_hash": "a4c8ce5c8c337cf066e40130e120241bb16ae0c40ef874618269301f602c4d6c", + "code_hash": "bcaa670f334b9fa7726aa85906e70125ad2cd4b7e7b62a8e39f8bdd06c975edb", + "example_hash": null, + "test_hash": "5e04901bfb8617572d25b38c955c9b34a4d7da39d3fc7a91ce94ae146fc7203d", + "test_files": { + "test_template_expander.py": "5e04901bfb8617572d25b38c955c9b34a4d7da39d3fc7a91ce94ae146fc7203d" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/template_registry_python.json b/.pdd/meta/template_registry_python.json new file mode 100644 index 0000000000..c00f5378cb --- /dev/null +++ b/.pdd/meta/template_registry_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.479489+00:00", + "command": "fix", + "prompt_hash": "28ec666c9c2ed6e91cf715d33bf544910ac0ccc825e10bca2fc3d514f65ea6b3", + "code_hash": "3b1b6758f82296d4d6aacef5bdd9a8fd597107ddd3cda8b8aa021102958308f2", + "example_hash": null, + "test_hash": "2fc00042ec2438d46a5c9ffb389fe1b54fe3aa610be391a83910130277431f21", + "test_files": { + "test_template_registry.py": "2fc00042ec2438d46a5c9ffb389fe1b54fe3aa610be391a83910130277431f21" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/test_context_packer_python.json b/.pdd/meta/test_context_packer_python.json new file mode 100644 index 0000000000..641f1d7345 --- /dev/null +++ b/.pdd/meta/test_context_packer_python.json @@ -0,0 +1,16 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.480073+00:00", + "command": "fix", + "prompt_hash": "e64578e078de825466c5b754a15fa32b4c50bdda7f7d34879d92d3c2efa1d6c7", + "code_hash": "27c7d14747d38df8edf24c8ef2ce1b7ca21d8f2eea38aec02ba06042ee144c0b", + "example_hash": "525c92e6dfd423097b29845182f7bfaca2ae8aea56da3bddbd00176e0480a509", + "test_hash": "f8d9545dfdace65a889ef4f4506716bb70cb4864453c6eb8717e5f14522e3abb", + "test_files": { + "test_test_context_packer.py": "f8d9545dfdace65a889ef4f4506716bb70cb4864453c6eb8717e5f14522e3abb" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/pytest_slicer.py": "c02a5488fe6f7248ed387636d5824cb2f1876544d3991e43ef253648a36e49a2" + } +} \ No newline at end of file diff --git a/.pdd/meta/trace_main_python.json b/.pdd/meta/trace_main_python.json new file mode 100644 index 0000000000..6b11576515 --- /dev/null +++ b/.pdd/meta/trace_main_python.json @@ -0,0 +1,18 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.480909+00:00", + "command": "fix", + "prompt_hash": "2e2223ee3b5d3af757758c871e32a57e8ede5c485cbd8db0f89a3ed04b73c874", + "code_hash": "48e9cc107b5af5668c031ba532b93a685a2399ae2d8bad482ef269dcd561a5b8", + "example_hash": "c1f43ebf55c05af801640f5f8331ee7a674aef9e3f383b0e5ffee7abc7246fe1", + "test_hash": "b36552a48543bb90256f2d5eebd344dd57be51b49c7fcfeaffb8ff3d35f6bd2d", + "test_files": { + "test_trace_main.py": "b36552a48543bb90256f2d5eebd344dd57be51b49c7fcfeaffb8ff3d35f6bd2d" + }, + "include_deps": { + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/trace_example.py": "de4d5d1ca347ea7ef9acd11dc80e86188917f61355e68db9c397ca6fd5108f99" + } +} \ No newline at end of file diff --git a/.pdd/meta/trace_python.json b/.pdd/meta/trace_python.json new file mode 100644 index 0000000000..dd3f9d37cd --- /dev/null +++ b/.pdd/meta/trace_python.json @@ -0,0 +1,19 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.482548+00:00", + "command": "fix", + "prompt_hash": "42c3207f2f44e00b5ae055219f4a518548fd3c129c037be591edc92f8ff9673f", + "code_hash": "9ff879812f1def2c14995b939a3b6541590ee68a7f62b25e57064ac7d642fbcb", + "example_hash": "de4d5d1ca347ea7ef9acd11dc80e86188917f61355e68db9c397ca6fd5108f99", + "test_hash": "c0d73d7b507978339d7b99706919ff1c14f9199cc6c8a77d1712e155bafdea82", + "test_files": { + "test_trace.py": "c0d73d7b507978339d7b99706919ff1c14f9199cc6c8a77d1712e155bafdea82", + "test_trace_main.py": "b36552a48543bb90256f2d5eebd344dd57be51b49c7fcfeaffb8ff3d35f6bd2d" + }, + "include_deps": { + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/track_cost_python.json b/.pdd/meta/track_cost_python.json index eeeedde189..669c46ccf6 100644 --- a/.pdd/meta/track_cost_python.json +++ b/.pdd/meta/track_cost_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.246.dev34", - "timestamp": "2026-05-21T04:24:21.384951+00:00", + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.483135+00:00", "command": "update", - "prompt_hash": "413975fcaf5d900d1c7edd631ad843a00c1ebe983e70812f86e689821c6218fa", - "code_hash": "3a1282ced73cc96c0428a006db619282c23c31aed6a50e2d427f106505ebd0ce", + "prompt_hash": "caff809a3e28802d4aa83f89a1b9b4c183e484713d91f8324444093817c272ad", + "code_hash": "b8776071f0f9c97a4fd10d6f9bf55faab99dde3757d47e836ef51d1c41b8513c", "example_hash": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6", - "test_hash": "2d272934a7ce4f40ffb1555451ed71fb09ff5fb451b7fd5a6893374968e99d0f", + "test_hash": "62f0edf3a67830bb686edd5de6b053b0d8bf1e861547608979616beef8ca6f29", "test_files": { - "test_track_cost.py": "2d272934a7ce4f40ffb1555451ed71fb09ff5fb451b7fd5a6893374968e99d0f" + "test_track_cost.py": "62f0edf3a67830bb686edd5de6b053b0d8bf1e861547608979616beef8ca6f29" }, "include_deps": {} -} +} \ No newline at end of file diff --git a/.pdd/meta/unfinished_prompt_python.json b/.pdd/meta/unfinished_prompt_python.json new file mode 100644 index 0000000000..9b92e78b68 --- /dev/null +++ b/.pdd/meta/unfinished_prompt_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.483932+00:00", + "command": "fix", + "prompt_hash": "5f54934748a49136dbd656ec52e97590e7fd493d4299dbf01f111a3a4b78ed3c", + "code_hash": "b012d1c6fab0579ae674d2d6e26be119dd9288c7ba2741b75af516be7a4564bf", + "example_hash": "5d4d74064e5b845391f035fb8631903ec2f39a54a90713f9c13dc24d2eb73c4f", + "test_hash": "c39f40da08752722ae6ee7279d1fcade01150a122bea1fbb76f02faa091cbf63", + "test_files": { + "test_unfinished_prompt.py": "c39f40da08752722ae6ee7279d1fcade01150a122bea1fbb76f02faa091cbf63" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f" + } +} \ No newline at end of file diff --git a/.pdd/meta/update_main_python.json b/.pdd/meta/update_main_python.json new file mode 100644 index 0000000000..a833e79ff4 --- /dev/null +++ b/.pdd/meta/update_main_python.json @@ -0,0 +1,28 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.486715+00:00", + "command": "fix", + "prompt_hash": "eb13aca686c206ea223dc9b6093627de4f37b158303323caa579311d65ac06e7", + "code_hash": "968fb4ec74af3245c758d975888e418c0ec2251edc14d56d545648538ccc10a6", + "example_hash": "9fe01fd19196c2604c91d101e49db849e0e1c9fabafeb2ad831a9c91b2f26416", + "test_hash": "d9edcd6b05c12d2121cce4cd042102a92e546025fe660611dd20a04235816e26", + "test_files": { + "test_update_main.py": "d9edcd6b05c12d2121cce4cd042102a92e546025fe660611dd20a04235816e26" + }, + "include_deps": { + "context/agentic_common_example.py": "c1538a115a3a33da228e7f6cc048f2a99023cd2c83a0efef382e49c477b24ad3", + "context/agentic_update_example.py": "967254cd1c636ac5ba09afa0446312ffc1f28d3041ed453a4c6588c931f722c4", + "context/api_key_scanner_example.py": "4b9f880a30445f25edffc394857ae0c218097726c41ab996a03fcbc4350b5482", + "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", + "context/auto_include_example.py": "0c278ed716298149777bc7082827eb8aa6d80dac264c66b6cded6871232f2df7", + "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", + "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", + "context/git_update_example.py": "811304cee2cb890879ee68a816aed49dff2e7b50cfdca3125e16e0ae99819574", + "context/metadata_sync_example.py": "704453b3386724eef225b61c48f2fe922e1a973ac211c494e1d955dd44bcca11", + "context/operation_log_example.py": "2660def7012d9b79bad3db33cf399ac603cc1c35dff0b064cbdd2638a013de1d", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/sync_determine_operation_example.py": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5", + "context/update_prompt_example.py": "56b9d8c7aa823c2996a3dc5741a47844e223bfd088366d74e48b6a099b5a11c4", + "pdd/validate_prompt_includes.py": "fa97b72a58534e255768634f928f4cfdd2130a7a4d8b296da3eefdf77d47855b" + } +} \ No newline at end of file diff --git a/.pdd/meta/update_model_costs_python.json b/.pdd/meta/update_model_costs_python.json new file mode 100644 index 0000000000..a9f49bc62e --- /dev/null +++ b/.pdd/meta/update_model_costs_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.487298+00:00", + "command": "fix", + "prompt_hash": "b21d140be33ba15fa136934ddb6862522cad498a6d33c9d4ffc9d7777dfa5755", + "code_hash": "ca390bd220734fbd7f4588b1a060628dfa9f298335af827f616902ff60a7f38d", + "example_hash": "90c9e0bab64d7495f55ba5876f8beab75ef40037508b5e9800ebc6afb5b55f5e", + "test_hash": "aae551a19112ec7eea9b151f2818fdf5c7b49d8ef23ca9371257e31b2df1e2fa", + "test_files": { + "test_update_model_costs.py": "aae551a19112ec7eea9b151f2818fdf5c7b49d8ef23ca9371257e31b2df1e2fa" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/update_prompt_python.json b/.pdd/meta/update_prompt_python.json new file mode 100644 index 0000000000..adf7b24b65 --- /dev/null +++ b/.pdd/meta/update_prompt_python.json @@ -0,0 +1,21 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.489099+00:00", + "command": "fix", + "prompt_hash": "1c92d709faafdcb2346184c538c57eff6afbbcf25e974f10d59f5eaaabf52916", + "code_hash": "4237e3fb40f2c1bb8f60f2d22305b80365f54c7834c1e97d997fcf803d52417e", + "example_hash": "56b9d8c7aa823c2996a3dc5741a47844e223bfd088366d74e48b6a099b5a11c4", + "test_hash": "dec5cce3090585615f7b97459b55c0800ac95e954f100ee73c88318f5cb99927", + "test_files": { + "test_update_prompt.py": "dec5cce3090585615f7b97459b55c0800ac95e954f100ee73c88318f5cb99927" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", + "context/change/14/initial_change.py": "fec3fba35a4710e02375bdb017bcf33882c2a3b690733fc9d5c6021c1602785c", + "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "pdd/llm_invoke.py": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", + "pdd/load_prompt_template.py": "903bb43e90d778fa04ba42cd8e329ac42e1b419bb372268f5955f26de43cce47", + "pdd/preprocess.py": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56" + } +} \ No newline at end of file diff --git a/.pdd/meta/user_story_tests_python.json b/.pdd/meta/user_story_tests_python.json new file mode 100644 index 0000000000..7a631b2060 --- /dev/null +++ b/.pdd/meta/user_story_tests_python.json @@ -0,0 +1,15 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.489840+00:00", + "command": "fix", + "prompt_hash": "18dd7b5a64063a5a942be847810537e6a22b436046bb698f1e891e3ebc2d5463", + "code_hash": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc", + "example_hash": "ae08c16469db958715911eeedc5916eb68fc71c90b605c4b78f6e93096873c86", + "test_hash": "8f9e336d3366396f4b8ff783eabf3c49df24a173c11a70972a5e13bc9ed43259", + "test_files": { + "test_user_story_tests.py": "8f9e336d3366396f4b8ff783eabf3c49df24a173c11a70972a5e13bc9ed43259" + }, + "include_deps": { + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file diff --git a/.pdd/meta/validate_prompt_includes_python.json b/.pdd/meta/validate_prompt_includes_python.json new file mode 100644 index 0000000000..877928170c --- /dev/null +++ b/.pdd/meta/validate_prompt_includes_python.json @@ -0,0 +1,13 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.490718+00:00", + "command": "fix", + "prompt_hash": "8a1052a5a135f25c7a0106f13a19977606a55fdfb4b06124f708c4db8ede6f54", + "code_hash": "fa97b72a58534e255768634f928f4cfdd2130a7a4d8b296da3eefdf77d47855b", + "example_hash": "675dfe58e40d3d3d67b4d586475fb365ed6c0a4852de4c3354f219c972323a69", + "test_hash": null, + "test_files": {}, + "include_deps": { + "context/auto_include_example.py": "0c278ed716298149777bc7082827eb8aa6d80dac264c66b6cded6871232f2df7" + } +} \ No newline at end of file diff --git a/.pdd/meta/xml_tagger_python.json b/.pdd/meta/xml_tagger_python.json new file mode 100644 index 0000000000..38fe13e9e1 --- /dev/null +++ b/.pdd/meta/xml_tagger_python.json @@ -0,0 +1,17 @@ +{ + "pdd_version": "0.0.299", + "timestamp": "2026-07-09T19:38:58.491578+00:00", + "command": "fix", + "prompt_hash": "9d86a05cae62bf793be21f5b99d1bd77a82299b1b85146da2cac32c74ca978dd", + "code_hash": "9cb3c692f9bf5c5eb54d758887a26268aafe51f327f0996e6476121f452ffbec", + "example_hash": "3b4606a0ac11cb728a5aa657d457312c83f2d710f53f4ac94d35675f7e911f60", + "test_hash": "fb48083ac847a187654f68c8fa45050199661306ebfa326366b3e7037d92fb25", + "test_files": { + "test_xml_tagger.py": "fb48083ac847a187654f68c8fa45050199661306ebfa326366b3e7037d92fb25" + }, + "include_deps": { + "context/llm_invoke_example.py": "3e66413118ec2f8e8940e7a835932920309aeeb775d23ce728d78299fb99e2ec", + "context/load_prompt_template_example.py": "a1cd6619182c6c951f5856dda4070e202875a5884bbfab9cc191d24de2f4951f", + "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" + } +} \ No newline at end of file From de91530dd8fedcf9b06b2256d31041fbb75a6d9b Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:49:13 -0700 Subject: [PATCH 11/30] Gate CI on `stamp_fingerprints.py --check` (part of pdd_cloud#2252) Add a step to the unit-tests job that fails when any committed .pdd/meta fingerprint is stale or missing, so the epoch stamp cannot silently rot again. The check is stdlib-only and needs no pdd import or network. Co-Authored-By: Claude --- .github/workflows/unit-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f79d1bd692..b84edda8c5 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -76,6 +76,9 @@ jobs: --deselect=tests/test_setup_tool.py::test_create_api_env_script_with_special_characters_zsh --deselect=tests/test_setup_tool.py::test_create_api_env_script_with_common_problematic_characters + - name: Check .pdd/meta fingerprints are current + run: python scripts/stamp_fingerprints.py --check + public-cli-regression: if: github.event_name != 'pull_request' || github.event.pull_request.draft != true name: Public CLI Regression From e7e701b40bcc9fe768034a762e8d50ec4e44c741 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 12:57:43 -0700 Subject: [PATCH 12/30] Restamp fingerprints after PR#1940 merge (sync_main, sync_orchestration, maintenance) The commit-all fingerprint gate flagged exactly the units #1940 touched; restamped with scripts/stamp_fingerprints.py per the new CONTRIBUTING policy. Co-Authored-By: Claude Fable 5 --- .pdd/meta/_keyring_timeout_python.json | 2 +- .../agentic_architecture_orchestrator_python.json | 2 +- .pdd/meta/agentic_architecture_python.json | 2 +- .pdd/meta/agentic_bug_orchestrator_python.json | 2 +- .pdd/meta/agentic_bug_python.json | 2 +- .pdd/meta/agentic_change_orchestrator_python.json | 2 +- .pdd/meta/agentic_change_python.json | 2 +- .pdd/meta/agentic_checkup_orchestrator_python.json | 2 +- .pdd/meta/agentic_checkup_python.json | 2 +- .pdd/meta/agentic_common_python.json | 2 +- .pdd/meta/agentic_common_worktree_python.json | 2 +- .pdd/meta/agentic_crash_python.json | 2 +- .pdd/meta/agentic_e2e_fix_orchestrator_python.json | 2 +- .pdd/meta/agentic_e2e_fix_python.json | 2 +- .pdd/meta/agentic_fix_python.json | 2 +- .pdd/meta/agentic_langtest_python.json | 2 +- .pdd/meta/agentic_multishot_python.json | 2 +- .pdd/meta/agentic_split_orchestrator_python.json | 2 +- .pdd/meta/agentic_split_python.json | 2 +- .pdd/meta/agentic_sync_python.json | 2 +- .pdd/meta/agentic_sync_runner_python.json | 2 +- .pdd/meta/agentic_test_generate_python.json | 2 +- .pdd/meta/agentic_test_orchestrator_python.json | 2 +- .pdd/meta/agentic_test_python.json | 2 +- .pdd/meta/agentic_update_python.json | 2 +- .pdd/meta/agentic_verify_python.json | 2 +- .pdd/meta/api_contract_slicer_python.json | 2 +- .pdd/meta/api_key_scanner_python.json | 2 +- .../meta/architecture_include_validation_python.json | 2 +- .pdd/meta/architecture_sync_python.json | 2 +- .pdd/meta/auth_service_python.json | 2 +- .pdd/meta/auto_deps_architecture_python.json | 2 +- .pdd/meta/auto_deps_main_python.json | 6 +++--- .pdd/meta/auto_include_python.json | 2 +- .pdd/meta/auto_update_python.json | 2 +- .pdd/meta/bug_main_python.json | 2 +- .pdd/meta/bug_to_unit_test_python.json | 2 +- .pdd/meta/change_main_python.json | 2 +- .pdd/meta/change_python.json | 2 +- .pdd/meta/checkup_agent_python.json | 2 +- .pdd/meta/checkup_file_selection_python.json | 2 +- .pdd/meta/checkup_gates_python.json | 2 +- .pdd/meta/checkup_interactive_main_python.json | 2 +- .pdd/meta/checkup_interactive_session_python.json | 2 +- .pdd/meta/checkup_planner_python.json | 2 +- .pdd/meta/checkup_prompt_apply_python.json | 2 +- .pdd/meta/checkup_prompt_main_python.json | 2 +- .pdd/meta/checkup_report_python.json | 2 +- .pdd/meta/checkup_review_loop_python.json | 2 +- .pdd/meta/checkup_simplify_claude_python.json | 2 +- .pdd/meta/checkup_simplify_engines_python.json | 2 +- .pdd/meta/checkup_simplify_python.json | 2 +- .pdd/meta/checkup_tools_python.json | 2 +- .pdd/meta/ci_detect_changed_modules_python.json | 2 +- .pdd/meta/ci_drift_heal_python.json | 2 +- .pdd/meta/ci_validation_python.json | 2 +- .pdd/meta/cli_branding_python.json | 2 +- .pdd/meta/cli_detector_python.json | 2 +- .pdd/meta/cli_status_python.json | 2 +- .pdd/meta/cli_theme_python.json | 2 +- .pdd/meta/cmd_test_main_python.json | 6 +++--- .pdd/meta/code_generator_main_python.json | 2 +- .pdd/meta/code_generator_python.json | 2 +- .pdd/meta/codex_subscription_python.json | 2 +- .pdd/meta/commands_analysis_python.json | 2 +- .pdd/meta/commands_auth_python.json | 2 +- .pdd/meta/commands_checkup_python.json | 2 +- .pdd/meta/commands_checkup_simplify_python.json | 2 +- .pdd/meta/commands_connect_python.json | 2 +- .pdd/meta/commands_context_python.json | 2 +- .pdd/meta/commands_contracts_python.json | 2 +- .pdd/meta/commands_firecrawl_python.json | 2 +- .pdd/meta/commands_fix_python.json | 2 +- .pdd/meta/commands_gate_python.json | 2 +- .pdd/meta/commands_generate_python.json | 2 +- .pdd/meta/commands_maintenance_python.json | 12 ++++++------ .pdd/meta/commands_misc_python.json | 6 +++--- .pdd/meta/commands_modify_python.json | 2 +- .pdd/meta/commands_prompt_python.json | 2 +- .pdd/meta/commands_replay_python.json | 2 +- .pdd/meta/commands_report_python.json | 2 +- .pdd/meta/commands_sessions_python.json | 2 +- .pdd/meta/commands_story_python.json | 2 +- .pdd/meta/commands_templates_python.json | 6 +++--- .pdd/meta/commands_utility_python.json | 6 +++--- .pdd/meta/commands_which_python.json | 2 +- .pdd/meta/comment_line_python.json | 2 +- .pdd/meta/compressed_sync_context_python.json | 2 +- .pdd/meta/config_resolution_python.json | 2 +- .pdd/meta/conflicts_in_prompts_python.json | 2 +- .pdd/meta/conflicts_main_python.json | 2 +- .pdd/meta/construct_paths_python.json | 6 +++--- .pdd/meta/content_selector_python.json | 2 +- .pdd/meta/context_audit_python.json | 2 +- .pdd/meta/context_generator_main_python.json | 2 +- .pdd/meta/context_generator_python.json | 2 +- .pdd/meta/context_snapshot_python.json | 2 +- .pdd/meta/continue_generation_python.json | 2 +- .pdd/meta/contract_check_python.json | 2 +- .pdd/meta/contract_ir_python.json | 2 +- .pdd/meta/core_cli_python.json | 2 +- .pdd/meta/core_cloud_python.json | 2 +- .pdd/meta/core_dump_python.json | 6 +++--- .pdd/meta/core_duplicate_cli_guard_python.json | 2 +- .pdd/meta/core_errors_python.json | 6 +++--- .pdd/meta/core_remote_session_python.json | 2 +- .pdd/meta/core_utils_python.json | 6 +++--- .pdd/meta/coverage_contracts_python.json | 2 +- .pdd/meta/crash_main_python.json | 2 +- .pdd/meta/detect_change_main_python.json | 6 +++--- .pdd/meta/detect_change_python.json | 2 +- .pdd/meta/durable_sync_runner_python.json | 2 +- .pdd/meta/edit_file_python.json | 2 +- .pdd/meta/embed_retrieve_python.json | 2 +- .pdd/meta/evidence_manifest_python.json | 2 +- .pdd/meta/evidence_store_python.json | 2 +- .pdd/meta/extracts_prune_python.json | 2 +- .pdd/meta/failure_classification_python.json | 2 +- .pdd/meta/find_section_python.json | 2 +- .pdd/meta/firecrawl_cache_python.json | 2 +- .pdd/meta/fix_code_loop_python.json | 2 +- .pdd/meta/fix_code_module_errors_python.json | 2 +- .pdd/meta/fix_error_loop_python.json | 2 +- .pdd/meta/fix_errors_from_unit_tests_python.json | 2 +- .pdd/meta/fix_focus_python.json | 2 +- .pdd/meta/fix_main_python.json | 2 +- .pdd/meta/fix_verification_errors_loop_python.json | 2 +- .pdd/meta/fix_verification_errors_python.json | 2 +- .pdd/meta/fix_verification_main_python.json | 2 +- .pdd/meta/gate_policy_python.json | 2 +- .pdd/meta/generate_model_catalog_python.json | 2 +- .pdd/meta/generate_output_paths_python.json | 6 +++--- .pdd/meta/generate_test_python.json | 2 +- .pdd/meta/generation_completion_python.json | 2 +- .pdd/meta/get_comment_python.json | 2 +- .pdd/meta/get_extension_python.json | 2 +- .pdd/meta/get_jwt_token_python.json | 2 +- .pdd/meta/get_language_python.json | 2 +- .pdd/meta/get_lint_commands_python.json | 2 +- .pdd/meta/get_run_command_python.json | 2 +- .pdd/meta/get_test_command_python.json | 2 +- .pdd/meta/git_porcelain_python.json | 2 +- .pdd/meta/git_update_python.json | 2 +- .pdd/meta/grounding_policy_python.json | 2 +- .pdd/meta/include_query_extractor_python.json | 2 +- .pdd/meta/increase_tests_python.json | 2 +- .pdd/meta/incremental_code_generator_python.json | 2 +- .pdd/meta/incremental_prd_architecture_python.json | 2 +- .pdd/meta/insert_includes_python.json | 2 +- .pdd/meta/install_completion_python.json | 2 +- .pdd/meta/llm_invoke_python.json | 2 +- .pdd/meta/load_prompt_template_python.json | 2 +- .pdd/meta/logo_animation_python.json | 2 +- .pdd/meta/metadata_sync_python.json | 2 +- .pdd/meta/model_tester_python.json | 2 +- .pdd/meta/one_session_sync_python.json | 2 +- .pdd/meta/operation_log_python.json | 2 +- .pdd/meta/path_resolution_python.json | 2 +- .pdd/meta/pddrc_initializer_python.json | 2 +- .pdd/meta/pin_example_hack_python.json | 2 +- .pdd/meta/postprocess_0_python.json | 2 +- .pdd/meta/postprocess_python.json | 2 +- .pdd/meta/pre_checkup_gate_python.json | 2 +- .pdd/meta/preprocess_main_python.json | 6 +++--- .pdd/meta/preprocess_python.json | 2 +- .pdd/meta/process_csv_change_python.json | 2 +- .pdd/meta/prompt_lint_python.json | 2 +- .pdd/meta/prompt_repair_python.json | 2 +- .pdd/meta/prompt_tester_python.json | 2 +- .pdd/meta/provider_manager_python.json | 2 +- .pdd/meta/pytest_output_python.json | 2 +- .pdd/meta/pytest_slicer_python.json | 2 +- .pdd/meta/python_env_detector_python.json | 2 +- .pdd/meta/reasoning_python.json | 2 +- .pdd/meta/remote_session_python.json | 2 +- .pdd/meta/render_mermaid_python.json | 2 +- .pdd/meta/resolved_sync_unit_python.json | 2 +- .pdd/meta/routing_policy_python.json | 2 +- .pdd/meta/run_generated_python.json | 2 +- .pdd/meta/server_app_python.json | 2 +- .pdd/meta/server_click_executor_python.json | 2 +- .pdd/meta/server_executor_python.json | 2 +- .pdd/meta/server_jobs_python.json | 2 +- .pdd/meta/server_models_python.json | 2 +- .pdd/meta/server_routes_architecture_python.json | 2 +- .pdd/meta/server_routes_auth_python.json | 2 +- .pdd/meta/server_routes_commands_python.json | 2 +- .pdd/meta/server_routes_config_python.json | 2 +- .pdd/meta/server_routes_extracts_python.json | 2 +- .pdd/meta/server_routes_files_python.json | 2 +- .pdd/meta/server_routes_prompts_python.json | 2 +- .pdd/meta/server_routes_websocket_python.json | 2 +- .pdd/meta/server_security_python.json | 2 +- .pdd/meta/server_terminal_spawner_python.json | 2 +- .pdd/meta/server_token_counter_python.json | 2 +- .pdd/meta/setup_tool_python.json | 2 +- .pdd/meta/split_main_python.json | 6 +++--- .pdd/meta/split_python.json | 2 +- .pdd/meta/split_validation_python.json | 2 +- .pdd/meta/story_coverage_python.json | 2 +- .pdd/meta/story_regression_gate_python.json | 2 +- .pdd/meta/story_regression_python.json | 2 +- .pdd/meta/story_test_generator_python.json | 2 +- .pdd/meta/summarize_directory_python.json | 2 +- .pdd/meta/sync_animation_python.json | 6 +++--- .pdd/meta/sync_determine_operation_python.json | 2 +- .pdd/meta/sync_main_python.json | 12 ++++++------ .pdd/meta/sync_orchestration_python.json | 12 ++++++------ .pdd/meta/sync_order_python.json | 2 +- .pdd/meta/sync_tui_python.json | 2 +- .pdd/meta/template_expander_python.json | 2 +- .pdd/meta/template_registry_python.json | 2 +- .pdd/meta/test_context_packer_python.json | 2 +- .pdd/meta/trace_main_python.json | 2 +- .pdd/meta/trace_python.json | 2 +- .pdd/meta/track_cost_python.json | 2 +- .pdd/meta/unfinished_prompt_python.json | 2 +- .pdd/meta/update_main_python.json | 2 +- .pdd/meta/update_model_costs_python.json | 2 +- .pdd/meta/update_prompt_python.json | 2 +- .pdd/meta/user_story_tests_python.json | 2 +- .pdd/meta/validate_prompt_includes_python.json | 2 +- .pdd/meta/xml_tagger_python.json | 2 +- 223 files changed, 266 insertions(+), 266 deletions(-) diff --git a/.pdd/meta/_keyring_timeout_python.json b/.pdd/meta/_keyring_timeout_python.json index acebdf0229..099b0efcab 100644 --- a/.pdd/meta/_keyring_timeout_python.json +++ b/.pdd/meta/_keyring_timeout_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.248150+00:00", + "timestamp": "2026-07-09T19:57:42.914816+00:00", "command": "fix", "prompt_hash": "febb0f9fd9f1e5f011acb73b44124f44ab3d401d53dc317912518f0798a075ad", "code_hash": "edf79dca88f4b80350a607c8978cbc74ed9b195eaa1e052172409d15529db1e1", diff --git a/.pdd/meta/agentic_architecture_orchestrator_python.json b/.pdd/meta/agentic_architecture_orchestrator_python.json index 2e331a3b01..3f516461c0 100644 --- a/.pdd/meta/agentic_architecture_orchestrator_python.json +++ b/.pdd/meta/agentic_architecture_orchestrator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.250822+00:00", + "timestamp": "2026-07-09T19:57:42.917207+00:00", "command": "fix", "prompt_hash": "d54fc246924930ac8e4dd5332bb00618220b4526eda5bd5267634430da6c0698", "code_hash": "72bdf8417b0f27eb676bdf858032368dc5325e076f665e8de46e080315d4dc37", diff --git a/.pdd/meta/agentic_architecture_python.json b/.pdd/meta/agentic_architecture_python.json index f4ceaa3086..60b10b3109 100644 --- a/.pdd/meta/agentic_architecture_python.json +++ b/.pdd/meta/agentic_architecture_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.251927+00:00", + "timestamp": "2026-07-09T19:57:42.917903+00:00", "command": "fix", "prompt_hash": "2c9c70c851e1af7c0af70a9c9ce960f96a6c3bcce7edadef570457bed96987d4", "code_hash": "09dd7b12d48fc7c0c0888157a5b366c42a077cd21b880f477ec763bca06edf28", diff --git a/.pdd/meta/agentic_bug_orchestrator_python.json b/.pdd/meta/agentic_bug_orchestrator_python.json index c3a6ad8cd9..1fb831719a 100644 --- a/.pdd/meta/agentic_bug_orchestrator_python.json +++ b/.pdd/meta/agentic_bug_orchestrator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.253859+00:00", + "timestamp": "2026-07-09T19:57:42.919579+00:00", "command": "fix", "prompt_hash": "074d1786614ee59558833746bede5e9236a9ceba635c5d8eb477880ea17eb9fd", "code_hash": "f04052d57db4963fbdab55cc1076d11f72e5e7a50c8c40a15e8d8266a6cd189c", diff --git a/.pdd/meta/agentic_bug_python.json b/.pdd/meta/agentic_bug_python.json index f26197387c..30b2f87e07 100644 --- a/.pdd/meta/agentic_bug_python.json +++ b/.pdd/meta/agentic_bug_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.255134+00:00", + "timestamp": "2026-07-09T19:57:42.920666+00:00", "command": "regenerate-public", "prompt_hash": "e0bd2e856ac450d59c9b284919708dd8771379b5a868f237a36174bec4d77efe", "code_hash": "ff878e298b3e1eb0639f99e68c88bb3507074208773f94440d413099fe896dc1", diff --git a/.pdd/meta/agentic_change_orchestrator_python.json b/.pdd/meta/agentic_change_orchestrator_python.json index a361725266..f245cd88fe 100644 --- a/.pdd/meta/agentic_change_orchestrator_python.json +++ b/.pdd/meta/agentic_change_orchestrator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.258693+00:00", + "timestamp": "2026-07-09T19:57:42.923956+00:00", "command": "fix", "prompt_hash": "c4a5d86036e7020281184875081fe00099168f15de45a3f6fe050b689193499f", "code_hash": "0eb021e1a02844b18205300373b4f45033faffa90c2eb681754403d26b864ad0", diff --git a/.pdd/meta/agentic_change_python.json b/.pdd/meta/agentic_change_python.json index 30031ec686..6c2b059372 100644 --- a/.pdd/meta/agentic_change_python.json +++ b/.pdd/meta/agentic_change_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.259922+00:00", + "timestamp": "2026-07-09T19:57:42.925004+00:00", "command": "fix", "prompt_hash": "629db7a1468e83aa831209e199f3058e30d83a572304487b9fcc89c6abb5bbdb", "code_hash": "3ef811c674502fe2038225a183bb25edd372c86f52ac2308261448d5127f92b0", diff --git a/.pdd/meta/agentic_checkup_orchestrator_python.json b/.pdd/meta/agentic_checkup_orchestrator_python.json index 10fa7ebfdb..f6b5ac16e3 100644 --- a/.pdd/meta/agentic_checkup_orchestrator_python.json +++ b/.pdd/meta/agentic_checkup_orchestrator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.261978+00:00", + "timestamp": "2026-07-09T19:57:42.926983+00:00", "command": "example", "prompt_hash": "f6ce089869d82405a523e00b735d95f9a6b36d26cdbf84858df60ec56d5ff234", "code_hash": "743a47b8a779974079f0ae3bb77090e47b3bd87606ac73a58cbf71e8b645d52e", diff --git a/.pdd/meta/agentic_checkup_python.json b/.pdd/meta/agentic_checkup_python.json index ad8345d301..77e712b0c4 100644 --- a/.pdd/meta/agentic_checkup_python.json +++ b/.pdd/meta/agentic_checkup_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.263817+00:00", + "timestamp": "2026-07-09T19:57:42.928922+00:00", "command": "test", "prompt_hash": "4b264564e6cdff492415aff67a3da2362933b7d802a1e1470d31d973d7d7566a", "code_hash": "d5b79fc009c5f935fd7fe70b2b2517f4f1f5c2c02a1231bf1d87ddbc4baba042", diff --git a/.pdd/meta/agentic_common_python.json b/.pdd/meta/agentic_common_python.json index b28b2dc8af..1d9e7a8703 100644 --- a/.pdd/meta/agentic_common_python.json +++ b/.pdd/meta/agentic_common_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.267777+00:00", + "timestamp": "2026-07-09T19:57:42.932639+00:00", "command": "fix", "prompt_hash": "300127d8bb7c0a9c48aecad8b02a9b9e1bead782d778e5e70f97b6f827eab308", "code_hash": "7b9b57eac64bac2b4fd18d4eea3d2feb3c7d99ff43f0ca1961a0bfd22a9576da", diff --git a/.pdd/meta/agentic_common_worktree_python.json b/.pdd/meta/agentic_common_worktree_python.json index 01e061654a..5e7bd22610 100644 --- a/.pdd/meta/agentic_common_worktree_python.json +++ b/.pdd/meta/agentic_common_worktree_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.268540+00:00", + "timestamp": "2026-07-09T19:57:42.933353+00:00", "command": "fix", "prompt_hash": "97ac2a6c3d3d0eff020a5508dddfe4c8e58530594d49372922a605fbcdeb9541", "code_hash": "9d54b21c1801d1f708340917eeb265435d968698392e501c2d8d214da6f4ee3f", diff --git a/.pdd/meta/agentic_crash_python.json b/.pdd/meta/agentic_crash_python.json index 5fa8d7d21e..6ae3350276 100644 --- a/.pdd/meta/agentic_crash_python.json +++ b/.pdd/meta/agentic_crash_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.269693+00:00", + "timestamp": "2026-07-09T19:57:42.934762+00:00", "command": "fix", "prompt_hash": "54aa28a454f27094d61f5ab79d3e52e379ffc0d3e240df1d7746e220846d6757", "code_hash": "78b5f9651c10d3ce474ff62b32f8f8953135847858fd6873c0824356068285c4", diff --git a/.pdd/meta/agentic_e2e_fix_orchestrator_python.json b/.pdd/meta/agentic_e2e_fix_orchestrator_python.json index d4b27d6899..16982df072 100644 --- a/.pdd/meta/agentic_e2e_fix_orchestrator_python.json +++ b/.pdd/meta/agentic_e2e_fix_orchestrator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.272493+00:00", + "timestamp": "2026-07-09T19:57:42.937324+00:00", "command": "test", "prompt_hash": "52d67e9a9cb487be694437418a6663657780aeb10c5196218f2c3bcf11bf1b09", "code_hash": "ad8df3444101a4ac3297db032f33b875c581c91fc615bc0f602a89b53113920e", diff --git a/.pdd/meta/agentic_e2e_fix_python.json b/.pdd/meta/agentic_e2e_fix_python.json index ead2594bbb..d788cd3e69 100644 --- a/.pdd/meta/agentic_e2e_fix_python.json +++ b/.pdd/meta/agentic_e2e_fix_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.273641+00:00", + "timestamp": "2026-07-09T19:57:42.938367+00:00", "command": "fix", "prompt_hash": "fc0a1a8955b1b6c6848985a7a037eb7595bc0134357d599cd34c85cf41f885be", "code_hash": "ab0b08e59e59b52431e7f4ba6a2b39f6267c7a43d0d45bf3573596c96649a57c", diff --git a/.pdd/meta/agentic_fix_python.json b/.pdd/meta/agentic_fix_python.json index 05bdd79a42..73284365e2 100644 --- a/.pdd/meta/agentic_fix_python.json +++ b/.pdd/meta/agentic_fix_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.274810+00:00", + "timestamp": "2026-07-09T19:57:42.939514+00:00", "command": "fix", "prompt_hash": "2aa547410ad5be7b47e1e69dcbfad7abb844b621a432730f24886a1e5014f350", "code_hash": "10fad4819034f9b2553c2fc584d2e977f490b1de43533219545a71ae19904179", diff --git a/.pdd/meta/agentic_langtest_python.json b/.pdd/meta/agentic_langtest_python.json index 31445fe8de..6897aa60bb 100644 --- a/.pdd/meta/agentic_langtest_python.json +++ b/.pdd/meta/agentic_langtest_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.275276+00:00", + "timestamp": "2026-07-09T19:57:42.939970+00:00", "command": "fix", "prompt_hash": "e63708a4640607ed61932a11b5c2f5c15a46e00fc1ad2113b9622414c4950f28", "code_hash": "7cb0be38d526d0a630500185427a9f76666d2b79385f7333a7608eb1fb33cfc9", diff --git a/.pdd/meta/agentic_multishot_python.json b/.pdd/meta/agentic_multishot_python.json index 4380f3da6c..fb0394097d 100644 --- a/.pdd/meta/agentic_multishot_python.json +++ b/.pdd/meta/agentic_multishot_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.276849+00:00", + "timestamp": "2026-07-09T19:57:42.941209+00:00", "command": "test", "prompt_hash": "0628511c4ecc1d928041296b13623b351b51e9596bd46485162b9b6a966b0073", "code_hash": "ecd0bfb52beb8172399b6da05f17d4ea308b22c4a5b10d5a32a98829c6e48edc", diff --git a/.pdd/meta/agentic_split_orchestrator_python.json b/.pdd/meta/agentic_split_orchestrator_python.json index d54a4daa2e..19964ed189 100644 --- a/.pdd/meta/agentic_split_orchestrator_python.json +++ b/.pdd/meta/agentic_split_orchestrator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.279678+00:00", + "timestamp": "2026-07-09T19:57:42.943814+00:00", "command": "fix", "prompt_hash": "e942762fcacc211d4f279733aa9a37f836c102b7bed4143cc5e6aa9f6d1236ae", "code_hash": "6e36d867ae932aa29f1aff078182179b6b0d3ddb86a99ddc5e3e23deaa110549", diff --git a/.pdd/meta/agentic_split_python.json b/.pdd/meta/agentic_split_python.json index 23d345b9ce..7596281cc3 100644 --- a/.pdd/meta/agentic_split_python.json +++ b/.pdd/meta/agentic_split_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.281302+00:00", + "timestamp": "2026-07-09T19:57:42.945307+00:00", "command": "fix", "prompt_hash": "216d6d2604fc6c2374b755be22a60994e34a73be331114b13ac7d8c5a5abc87e", "code_hash": "044ff030cd6896b3a20507b6797033c2784fc2c17826024a304cea446d255038", diff --git a/.pdd/meta/agentic_sync_python.json b/.pdd/meta/agentic_sync_python.json index 6765f7ad0f..95a3c62eeb 100644 --- a/.pdd/meta/agentic_sync_python.json +++ b/.pdd/meta/agentic_sync_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.283498+00:00", + "timestamp": "2026-07-09T19:57:42.947381+00:00", "command": "fix", "prompt_hash": "b46925c0018d0b91841bee732c5da57c6d1d71b8b848d57543005120a6885f08", "code_hash": "b98bddf2b04560eb402d856aa6dd9a7077e731123edfb3bf9cbd80064681d879", diff --git a/.pdd/meta/agentic_sync_runner_python.json b/.pdd/meta/agentic_sync_runner_python.json index 7fe64b7703..11b02b4214 100644 --- a/.pdd/meta/agentic_sync_runner_python.json +++ b/.pdd/meta/agentic_sync_runner_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.285767+00:00", + "timestamp": "2026-07-09T19:57:42.949098+00:00", "command": "fix", "prompt_hash": "1039b82c0ca610342a21046297c0798f86a4f99217ebe2725b147a7f3cca2401", "code_hash": "572f865d1bdbddf4827d5f308eb72030c3ed085c4f570284cbda8c961d01af2d", diff --git a/.pdd/meta/agentic_test_generate_python.json b/.pdd/meta/agentic_test_generate_python.json index bca10c01ba..223ffa4bb2 100644 --- a/.pdd/meta/agentic_test_generate_python.json +++ b/.pdd/meta/agentic_test_generate_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.286814+00:00", + "timestamp": "2026-07-09T19:57:42.949865+00:00", "command": "fix", "prompt_hash": "028c512165adf77ee126b1d10be74c53df990fbf4206b919b42cfae966d4d13f", "code_hash": "5c34b242014d6cc56a1e9504bc649032ecea24fc09c50754afad2d421053020e", diff --git a/.pdd/meta/agentic_test_orchestrator_python.json b/.pdd/meta/agentic_test_orchestrator_python.json index 3e54fb2f28..ee9d1cd883 100644 --- a/.pdd/meta/agentic_test_orchestrator_python.json +++ b/.pdd/meta/agentic_test_orchestrator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.287938+00:00", + "timestamp": "2026-07-09T19:57:42.950814+00:00", "command": "fix", "prompt_hash": "eff9420f13230d7a96a6ff94c36ab5b49cfe47d9cbc47a1cb1532a566aaa0239", "code_hash": "38435707d35f64e685a3789ff8752768ffcfffed927af11b9dd90ba08ab93ff9", diff --git a/.pdd/meta/agentic_test_python.json b/.pdd/meta/agentic_test_python.json index a3a171fe35..93fa1209a4 100644 --- a/.pdd/meta/agentic_test_python.json +++ b/.pdd/meta/agentic_test_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.289069+00:00", + "timestamp": "2026-07-09T19:57:42.951799+00:00", "command": "fix", "prompt_hash": "ddab846232bad2745161f117a908bb88f9050878fe61f944e7e18dece79dad61", "code_hash": "e9834cc73b9d125bc46354b262a9b17067150f044055edda5529adb695a0b372", diff --git a/.pdd/meta/agentic_update_python.json b/.pdd/meta/agentic_update_python.json index a9b27200c7..1671674f6c 100644 --- a/.pdd/meta/agentic_update_python.json +++ b/.pdd/meta/agentic_update_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.290902+00:00", + "timestamp": "2026-07-09T19:57:42.953557+00:00", "command": "fix", "prompt_hash": "3f8ff49dcf8a62526143f7d4c06c0780cc0180351c1da693eeb28e3b37d3aa0c", "code_hash": "f0bd8afbbb4cbbc8dcde8116061a09fdd7a888daa540b48eb46b360153a5c6a4", diff --git a/.pdd/meta/agentic_verify_python.json b/.pdd/meta/agentic_verify_python.json index 43347b3772..4a2ff3175a 100644 --- a/.pdd/meta/agentic_verify_python.json +++ b/.pdd/meta/agentic_verify_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.291780+00:00", + "timestamp": "2026-07-09T19:57:42.954383+00:00", "command": "fix", "prompt_hash": "9c95d066438cd9e009e36875214172c588a7db46d1805dddbc74018b930a179f", "code_hash": "ede66dcf689550aaebe8991e6ba90eaa2502315789de90faaa507c8944cb5060", diff --git a/.pdd/meta/api_contract_slicer_python.json b/.pdd/meta/api_contract_slicer_python.json index 7e2323591b..5419b41941 100644 --- a/.pdd/meta/api_contract_slicer_python.json +++ b/.pdd/meta/api_contract_slicer_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.292235+00:00", + "timestamp": "2026-07-09T19:57:42.954803+00:00", "command": "fix", "prompt_hash": "79768843f184f50c60dd2caf94ba173f115b04a4f6fc50eca601de9008c710d5", "code_hash": "0170b39f8ac42c0ff86ea426c1f98449158a5f3321474422a252397283c77f3e", diff --git a/.pdd/meta/api_key_scanner_python.json b/.pdd/meta/api_key_scanner_python.json index 75c2c83e00..96abd2d9e4 100644 --- a/.pdd/meta/api_key_scanner_python.json +++ b/.pdd/meta/api_key_scanner_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.292556+00:00", + "timestamp": "2026-07-09T19:57:42.955109+00:00", "command": "fix", "prompt_hash": "4d93f1716d60a12ac6a6730482c96f1a7242ecdc57b9d3c28dafada9c137c4b9", "code_hash": "45cc7a5ac182630ed7a04980cff5430658cc79989904264cf1556c04311a0610", diff --git a/.pdd/meta/architecture_include_validation_python.json b/.pdd/meta/architecture_include_validation_python.json index 7bb31c633e..f089132dc3 100644 --- a/.pdd/meta/architecture_include_validation_python.json +++ b/.pdd/meta/architecture_include_validation_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.293341+00:00", + "timestamp": "2026-07-09T19:57:42.955847+00:00", "command": "fix", "prompt_hash": "bba83e01cec00a1a3c1fb7a9f174705bd169cb7c42cff69ac9a83d611a53e957", "code_hash": "b412fed88e36c21751565c0c94a9dfe314c3a280d04ab0a2e82f1ea17ca81c08", diff --git a/.pdd/meta/architecture_sync_python.json b/.pdd/meta/architecture_sync_python.json index eeb79bab78..0e39290d91 100644 --- a/.pdd/meta/architecture_sync_python.json +++ b/.pdd/meta/architecture_sync_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.294436+00:00", + "timestamp": "2026-07-09T19:57:42.956532+00:00", "command": "example", "prompt_hash": "2fb502ebb1466361da7c064975239bc9e9bbf2e80bb3b2da95e3027862f2dd99", "code_hash": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", diff --git a/.pdd/meta/auth_service_python.json b/.pdd/meta/auth_service_python.json index 100b2d7596..d06d1253fc 100644 --- a/.pdd/meta/auth_service_python.json +++ b/.pdd/meta/auth_service_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.295456+00:00", + "timestamp": "2026-07-09T19:57:42.957266+00:00", "command": "fix", "prompt_hash": "f78505eb6667a42e4995a591d706334faf15fa7f164b659877bb5c7f343d2df0", "code_hash": "a4b689e00ad7106bb775f1b365d67b3d5106f5e4c7021d7ac751468652d7693c", diff --git a/.pdd/meta/auto_deps_architecture_python.json b/.pdd/meta/auto_deps_architecture_python.json index 40edef93fe..addedf444e 100644 --- a/.pdd/meta/auto_deps_architecture_python.json +++ b/.pdd/meta/auto_deps_architecture_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.296571+00:00", + "timestamp": "2026-07-09T19:57:42.958283+00:00", "command": "fix", "prompt_hash": "2e31837c35515ab3922301a394228ab699115c424a9b3a0a42bb26e673544893", "code_hash": "d20e3525f49abb1c4d4d923ed619e9f0b26cb29cbca12df2f22479b8d3926a44", diff --git a/.pdd/meta/auto_deps_main_python.json b/.pdd/meta/auto_deps_main_python.json index 744683730a..7fe3b2828d 100644 --- a/.pdd/meta/auto_deps_main_python.json +++ b/.pdd/meta/auto_deps_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.298791+00:00", + "timestamp": "2026-07-09T19:57:42.960495+00:00", "command": "fix", - "prompt_hash": "e2de0f2e2216a9bd6a1f257ec4f0964dbf2cd67a8d0295cf9701820dc8cc287b", + "prompt_hash": "811c79863b474bbbf78cd137e35aa2024e9a95b256752709328bbd5915a8637a", "code_hash": "b5df06f550c4dc0151af20f911eb19552d494cfb9853a7f35bd67c096a40581a", "example_hash": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "test_hash": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20", @@ -10,7 +10,7 @@ "test_auto_deps_main.py": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/insert_includes_example.py": "c304bf4656f75fa26192c92b3eb0422a903d8a1bc82dda3158dc9f184b337873", diff --git a/.pdd/meta/auto_include_python.json b/.pdd/meta/auto_include_python.json index 02da6911ff..bfac3d1a4f 100644 --- a/.pdd/meta/auto_include_python.json +++ b/.pdd/meta/auto_include_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.300193+00:00", + "timestamp": "2026-07-09T19:57:42.961875+00:00", "command": "fix", "prompt_hash": "47d0a02c54c54e2b9835a96321fe76ae283abc9467c20af1e5363312b960e27c", "code_hash": "5bcd43f2318cb317a8fe7cbbc510a8bd020ddf8b2b6cfa5dafbf128b37586b8a", diff --git a/.pdd/meta/auto_update_python.json b/.pdd/meta/auto_update_python.json index db7ce41e1a..13da371736 100644 --- a/.pdd/meta/auto_update_python.json +++ b/.pdd/meta/auto_update_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.300548+00:00", + "timestamp": "2026-07-09T19:57:42.962172+00:00", "command": "fix", "prompt_hash": "072c1e4211367cc131c7aef9b844c8590e3a0642afafda817bfbf19179227e80", "code_hash": "0945c48a916c2783701c5aac8da7e2f033c4a2c0939f1cb96dab30bdb39eadba", diff --git a/.pdd/meta/bug_main_python.json b/.pdd/meta/bug_main_python.json index 0877f35b29..035a2948a4 100644 --- a/.pdd/meta/bug_main_python.json +++ b/.pdd/meta/bug_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.301922+00:00", + "timestamp": "2026-07-09T19:57:42.963494+00:00", "command": "fix", "prompt_hash": "9eb6e4dcae71fb61e683ddfe07362e0e6668ffa18eca3160585781e6e4201df2", "code_hash": "add508e807f11ea3bf90b1a1038307c2f491fdc7cbf338029e097b987aff3ae2", diff --git a/.pdd/meta/bug_to_unit_test_python.json b/.pdd/meta/bug_to_unit_test_python.json index 22f5f5fd06..f5f15c2dbf 100644 --- a/.pdd/meta/bug_to_unit_test_python.json +++ b/.pdd/meta/bug_to_unit_test_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.303093+00:00", + "timestamp": "2026-07-09T19:57:42.964616+00:00", "command": "fix", "prompt_hash": "f0c0cb57741620d320c1e7248e44e033b6c929187186268bd636538ea3f2efb3", "code_hash": "06842a372290a414035bcf89c011ff457e111d14a253c2a4dc4a6516b9040add", diff --git a/.pdd/meta/change_main_python.json b/.pdd/meta/change_main_python.json index 7f1244d64c..9dd58ea4ae 100644 --- a/.pdd/meta/change_main_python.json +++ b/.pdd/meta/change_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.304544+00:00", + "timestamp": "2026-07-09T19:57:42.966086+00:00", "command": "fix", "prompt_hash": "e8db62d56db28f59310080c7bd87fce607be32fb8d92f03b562b7ef73d52a376", "code_hash": "a350dfbafdcee8275e86760417f194ea3154b17417a32137a49f36f2e3e182de", diff --git a/.pdd/meta/change_python.json b/.pdd/meta/change_python.json index cbe45a7d2f..98615809e7 100644 --- a/.pdd/meta/change_python.json +++ b/.pdd/meta/change_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.306496+00:00", + "timestamp": "2026-07-09T19:57:42.967735+00:00", "command": "fix", "prompt_hash": "78e1d54b350c8096a9652d858a7f41406b224756dc55a4894c1d97df37f14698", "code_hash": "d66d22f9ef9e6a80574d91b115bf72aac534d238dd8a8085d5744e1a8c1562a3", diff --git a/.pdd/meta/checkup_agent_python.json b/.pdd/meta/checkup_agent_python.json index 56d8df9555..5cab8d3303 100644 --- a/.pdd/meta/checkup_agent_python.json +++ b/.pdd/meta/checkup_agent_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.306916+00:00", + "timestamp": "2026-07-09T19:57:42.968264+00:00", "command": "fix", "prompt_hash": "653a638d7dbede994e83a15482b572c27f5d5a27df3e8f20ad244544a5a9318e", "code_hash": "d091af7573d71153ee8106191cd8e732bd098cfcfb50f40e8bdbb4acb41ec41d", diff --git a/.pdd/meta/checkup_file_selection_python.json b/.pdd/meta/checkup_file_selection_python.json index e0e9b9d7b6..649b496be6 100644 --- a/.pdd/meta/checkup_file_selection_python.json +++ b/.pdd/meta/checkup_file_selection_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.307283+00:00", + "timestamp": "2026-07-09T19:57:42.968631+00:00", "command": "fix", "prompt_hash": "f49ed34a0a7be2d0539d9b5b1cbd1f8aec20537a4f5a4b2d97d514ebbdfe0f51", "code_hash": "2139db4e6952575d8a094096f37687c5918619cf5a5733bd7d47d27717be9ab2", diff --git a/.pdd/meta/checkup_gates_python.json b/.pdd/meta/checkup_gates_python.json index c391b9ef42..c6f21d8e24 100644 --- a/.pdd/meta/checkup_gates_python.json +++ b/.pdd/meta/checkup_gates_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.308370+00:00", + "timestamp": "2026-07-09T19:57:42.969733+00:00", "command": "fix", "prompt_hash": "40c44f6befb609de46b5441e473bdedf9192cf820b13639ed278252a542c79ab", "code_hash": "b6086954a93e0495661e6ca39d96b3079b928d13308bf0fcd6a16b1e0b5f511c", diff --git a/.pdd/meta/checkup_interactive_main_python.json b/.pdd/meta/checkup_interactive_main_python.json index 0a00105fec..fcd0d1ae18 100644 --- a/.pdd/meta/checkup_interactive_main_python.json +++ b/.pdd/meta/checkup_interactive_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.308604+00:00", + "timestamp": "2026-07-09T19:57:42.969978+00:00", "command": "fix", "prompt_hash": "5abaf9a3e2e5ff24c024ff03f07ccc9c7686a13cd389f0e98870a78fd97cb1cb", "code_hash": "82ef9d91f959a52ba334a15c89b9fa94afa164d6b69eae0f0c029579163035f2", diff --git a/.pdd/meta/checkup_interactive_session_python.json b/.pdd/meta/checkup_interactive_session_python.json index b5fd3bfdca..30b8d34635 100644 --- a/.pdd/meta/checkup_interactive_session_python.json +++ b/.pdd/meta/checkup_interactive_session_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.309079+00:00", + "timestamp": "2026-07-09T19:57:42.970451+00:00", "command": "fix", "prompt_hash": "56f9f2ddfd309e93c49b22a6b319618f4e9254f433bceb6ff9e10aaa1c4951f6", "code_hash": "9a06207e7c3a1c8c53f38c9029cf9fb24baf3a8f8be6170eee420aadf604bde7", diff --git a/.pdd/meta/checkup_planner_python.json b/.pdd/meta/checkup_planner_python.json index 06046b9d07..32f0b540d7 100644 --- a/.pdd/meta/checkup_planner_python.json +++ b/.pdd/meta/checkup_planner_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.309307+00:00", + "timestamp": "2026-07-09T19:57:42.970668+00:00", "command": "fix", "prompt_hash": "6d3d2dc712729d789b6293c33c411fb8cff975dcb17ebbd38ea7138b876ce241", "code_hash": "2ab02a1c2c971b16b700c6ecf1062eafcaa053aec8c8cd43c9864a6cad5dbd1b", diff --git a/.pdd/meta/checkup_prompt_apply_python.json b/.pdd/meta/checkup_prompt_apply_python.json index a29db2941a..e5fc17242d 100644 --- a/.pdd/meta/checkup_prompt_apply_python.json +++ b/.pdd/meta/checkup_prompt_apply_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.309570+00:00", + "timestamp": "2026-07-09T19:57:42.970922+00:00", "command": "fix", "prompt_hash": "95685575e722bfed5574086d8e01f31ec743e6f4046b101032748e7848efb14c", "code_hash": "d72f795e03a2eb9b60023ee3f2e23975d10a61c7deb0daeb319030e5a1f92206", diff --git a/.pdd/meta/checkup_prompt_main_python.json b/.pdd/meta/checkup_prompt_main_python.json index 3fbd8d0ea6..2e63034673 100644 --- a/.pdd/meta/checkup_prompt_main_python.json +++ b/.pdd/meta/checkup_prompt_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.311541+00:00", + "timestamp": "2026-07-09T19:57:42.972923+00:00", "command": "fix", "prompt_hash": "a7e1a43ec7e38aecd73d9b4acaf142413c48d6df461d524c122f22bac10df8ef", "code_hash": "538367ba6b7fa74d9f86ba6d1235219598f7a124c58cf00ad0abf6cf027526dc", diff --git a/.pdd/meta/checkup_report_python.json b/.pdd/meta/checkup_report_python.json index dd50b28abc..c090511165 100644 --- a/.pdd/meta/checkup_report_python.json +++ b/.pdd/meta/checkup_report_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.311833+00:00", + "timestamp": "2026-07-09T19:57:42.973241+00:00", "command": "fix", "prompt_hash": "2b1ffbc310805ac63bcd051f10ce03159534752ea729a6b11e91bf8e27400188", "code_hash": "1dbd1ce70b5bad244814044cda35b08e31f3830ade98aa7abadf55913d156fc8", diff --git a/.pdd/meta/checkup_review_loop_python.json b/.pdd/meta/checkup_review_loop_python.json index 0463002e29..0fbbb653e0 100644 --- a/.pdd/meta/checkup_review_loop_python.json +++ b/.pdd/meta/checkup_review_loop_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.314978+00:00", + "timestamp": "2026-07-09T19:57:42.975709+00:00", "command": "fix", "prompt_hash": "a4ec8ed0458adb258d495ea6444d014d4898e004814ee8447359816658d26be5", "code_hash": "8addb7e16d4f1b4e36ce8214748c8fdae9db53a09802d29a872b046d687bf2d1", diff --git a/.pdd/meta/checkup_simplify_claude_python.json b/.pdd/meta/checkup_simplify_claude_python.json index d57e62572c..f1fa5b929a 100644 --- a/.pdd/meta/checkup_simplify_claude_python.json +++ b/.pdd/meta/checkup_simplify_claude_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.315826+00:00", + "timestamp": "2026-07-09T19:57:42.976114+00:00", "command": "fix", "prompt_hash": "d3587f96ae7eee752af14011c3ecceb94fb0c20691132fe5ef7aaf82caa8e083", "code_hash": "0dd6846d6b5e9ec63ac71fa6474eb84f06bc2dbb5f168e9c01eeeb2eee7f1c7a", diff --git a/.pdd/meta/checkup_simplify_engines_python.json b/.pdd/meta/checkup_simplify_engines_python.json index 6f86e335a2..2afddeb532 100644 --- a/.pdd/meta/checkup_simplify_engines_python.json +++ b/.pdd/meta/checkup_simplify_engines_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.316384+00:00", + "timestamp": "2026-07-09T19:57:42.976505+00:00", "command": "fix", "prompt_hash": "0eaef948b5e725a8dbc1a14b1240b52946cbb9893401d0a6b001004c93267086", "code_hash": "9009191475a97901ad9b4eac39a682f55b4789297022d9c3752aba4126ea3230", diff --git a/.pdd/meta/checkup_simplify_python.json b/.pdd/meta/checkup_simplify_python.json index 2a13346ec9..83cc1488c4 100644 --- a/.pdd/meta/checkup_simplify_python.json +++ b/.pdd/meta/checkup_simplify_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.316852+00:00", + "timestamp": "2026-07-09T19:57:42.977039+00:00", "command": "fix", "prompt_hash": "3a0b375fbd9294ef119fed542d772ad16485ab579fe15fd55619e363d08e10a2", "code_hash": "6ec8b1694b0ec8c9955261fff159b1a86397d54f24a0f95ea5243ac9cbd6df7f", diff --git a/.pdd/meta/checkup_tools_python.json b/.pdd/meta/checkup_tools_python.json index 235d3cf996..9a5d3b80fa 100644 --- a/.pdd/meta/checkup_tools_python.json +++ b/.pdd/meta/checkup_tools_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.317113+00:00", + "timestamp": "2026-07-09T19:57:42.977255+00:00", "command": "fix", "prompt_hash": "df087676e5581e2e05a7d6daa036b5e1113cccd5c837a1b4a3508b890e1da118", "code_hash": "d11c11dc9670827619d71214c4d7d3b6535c13460a67d8290af83c34f050e757", diff --git a/.pdd/meta/ci_detect_changed_modules_python.json b/.pdd/meta/ci_detect_changed_modules_python.json index 5151de47cb..c2f6ed662d 100644 --- a/.pdd/meta/ci_detect_changed_modules_python.json +++ b/.pdd/meta/ci_detect_changed_modules_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.318042+00:00", + "timestamp": "2026-07-09T19:57:42.978233+00:00", "command": "fix", "prompt_hash": "ef30764861a3080d2fb093ca747f86a3f46bba733a0cdc6a5634efc1b36a73a2", "code_hash": "0d77f7c40e1498558218ea0d552f09bc9d02e128be4dca789f6b0f13dfc76007", diff --git a/.pdd/meta/ci_drift_heal_python.json b/.pdd/meta/ci_drift_heal_python.json index 5b2caa4e9d..60430663ff 100644 --- a/.pdd/meta/ci_drift_heal_python.json +++ b/.pdd/meta/ci_drift_heal_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.320450+00:00", + "timestamp": "2026-07-09T19:57:42.980154+00:00", "command": "fix", "prompt_hash": "09fe741d2541f30d7ece2447ba91fa8cf91bb4c9ef937810abe6e622649b68df", "code_hash": "4866e9be8fc9513c4d7a5cd03c5eff4c7ebb3a639024c91682322d77f462b94a", diff --git a/.pdd/meta/ci_validation_python.json b/.pdd/meta/ci_validation_python.json index 669af9f04a..36afbda888 100644 --- a/.pdd/meta/ci_validation_python.json +++ b/.pdd/meta/ci_validation_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.321560+00:00", + "timestamp": "2026-07-09T19:57:42.981130+00:00", "command": "fix", "prompt_hash": "6627ace940bcffc3b9cd754c83014635f2949a11c32f6b133e6f209ddc908d3b", "code_hash": "01935b7b312fcbc3a1812290f6d69fe5d65ddf3530f546c8da729bb8d6a3aeae", diff --git a/.pdd/meta/cli_branding_python.json b/.pdd/meta/cli_branding_python.json index 2f1d81baf7..15adb925f4 100644 --- a/.pdd/meta/cli_branding_python.json +++ b/.pdd/meta/cli_branding_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.321850+00:00", + "timestamp": "2026-07-09T19:57:42.981391+00:00", "command": "fix", "prompt_hash": "2b1c46c67c15235c43a7aacbaba313a0a98dc21383d3b91507173eabfd588fba", "code_hash": "fc9056e722b00d532aafc3c051eab4d6ba3f5cb7a3aaa4492194202cc8000a24", diff --git a/.pdd/meta/cli_detector_python.json b/.pdd/meta/cli_detector_python.json index e3f120dbff..1fb551ceee 100644 --- a/.pdd/meta/cli_detector_python.json +++ b/.pdd/meta/cli_detector_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.322290+00:00", + "timestamp": "2026-07-09T19:57:42.981780+00:00", "command": "fix", "prompt_hash": "4bcecc483a368af1d6dc9d9f0b12e608e760b179c5b03c2c4d866a06cbdbe59b", "code_hash": "78b4e788b206d2902296351faecfcc8e2ced44b9dbc696837b4c7bd45f1fce7a", diff --git a/.pdd/meta/cli_status_python.json b/.pdd/meta/cli_status_python.json index 628488df9a..be1ecf0c85 100644 --- a/.pdd/meta/cli_status_python.json +++ b/.pdd/meta/cli_status_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.322589+00:00", + "timestamp": "2026-07-09T19:57:42.982052+00:00", "command": "fix", "prompt_hash": "121ff116fa307d8034c8f8826f0e1382fd6467fe4eb9d5ef480030901d114e57", "code_hash": "9aacc600635c5a2e6f5d9b2ef028ba701b3d6605b23e497aabc0382a6d8ef1d5", diff --git a/.pdd/meta/cli_theme_python.json b/.pdd/meta/cli_theme_python.json index bb7b0cc213..02655ca25d 100644 --- a/.pdd/meta/cli_theme_python.json +++ b/.pdd/meta/cli_theme_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.323046+00:00", + "timestamp": "2026-07-09T19:57:42.982343+00:00", "command": "fix", "prompt_hash": "92ea1f8c1b4039771ee67668a380f44dffc6d976751dd1ec78a498f2c55defb5", "code_hash": "00d434d8798de28ba50dfc195655f57e9ac671cf178c6d77a473dd18e5cd1b06", diff --git a/.pdd/meta/cmd_test_main_python.json b/.pdd/meta/cmd_test_main_python.json index e7f37fc613..6da16ea9d5 100644 --- a/.pdd/meta/cmd_test_main_python.json +++ b/.pdd/meta/cmd_test_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.325051+00:00", + "timestamp": "2026-07-09T19:57:42.984223+00:00", "command": "fix", - "prompt_hash": "fd8c3c5aabaf7330982ece58d638099c28e7ae5bb97f2d868ee528190ca71b8d", + "prompt_hash": "0c5ebbcaf3004ef236bf63fcc99a9694d0042648e179b922b8610734ad6046df", "code_hash": "cc809a1c54c8f4aa2ac4dd9e391d89df4b4e1be2dacc42f0a71306b4a666cf3d", "example_hash": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "test_hash": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643", @@ -10,7 +10,7 @@ "test_cmd_test_main.py": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/cloud_function_call.py": "62ac7724ce2e3eddbba2b743bd7aa5790dbed34eae01e77e0252c4cc6358c95e", diff --git a/.pdd/meta/code_generator_main_python.json b/.pdd/meta/code_generator_main_python.json index b58274d6a2..3364012888 100644 --- a/.pdd/meta/code_generator_main_python.json +++ b/.pdd/meta/code_generator_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.329127+00:00", + "timestamp": "2026-07-09T19:57:42.988134+00:00", "command": "example", "prompt_hash": "b0e5511b3cfab37280bfa33b4def679b78664af37da564d77d56a324e0466670", "code_hash": "e83cc9bd8890d032fcf63001b83feb766d632ab08d00e20110e489e0386962b4", diff --git a/.pdd/meta/code_generator_python.json b/.pdd/meta/code_generator_python.json index 1ca90c5ced..4f21958e0b 100644 --- a/.pdd/meta/code_generator_python.json +++ b/.pdd/meta/code_generator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.330448+00:00", + "timestamp": "2026-07-09T19:57:42.989446+00:00", "command": "fix", "prompt_hash": "2db9dd103925fef2b56138d3fa0056d86d30d1026e60ea17477d892d6df1357e", "code_hash": "33235364b431edbb0fb1c4d8eb03fa21a3b776e07ea585530c19212da20c486d", diff --git a/.pdd/meta/codex_subscription_python.json b/.pdd/meta/codex_subscription_python.json index b6df612848..cd93bd6c52 100644 --- a/.pdd/meta/codex_subscription_python.json +++ b/.pdd/meta/codex_subscription_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.330840+00:00", + "timestamp": "2026-07-09T19:57:42.989790+00:00", "command": "fix", "prompt_hash": "17eedbc09a256171e39540fdd62097d30a4d66fba0fb20843b994315e2d5fc3c", "code_hash": "4a3ff334aa58b5f8e004f2eff9a67a041ed0a4d374a6646090239d8b6411df1a", diff --git a/.pdd/meta/commands_analysis_python.json b/.pdd/meta/commands_analysis_python.json index 38b0e36622..bbb3a867b2 100644 --- a/.pdd/meta/commands_analysis_python.json +++ b/.pdd/meta/commands_analysis_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.332634+00:00", + "timestamp": "2026-07-09T19:57:42.991246+00:00", "command": "fix", "prompt_hash": "f618f0ee1b3dfb720406f22d8c6dacf83a0e99942a0e7432a6d3d29526f0c4b7", "code_hash": "a553780c2267d05af75ea447ea01e94519ab7b5a27e940abec6183797e7fb1ba", diff --git a/.pdd/meta/commands_auth_python.json b/.pdd/meta/commands_auth_python.json index 63dad4b12f..bf69644811 100644 --- a/.pdd/meta/commands_auth_python.json +++ b/.pdd/meta/commands_auth_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.334010+00:00", + "timestamp": "2026-07-09T19:57:42.992351+00:00", "command": "fix", "prompt_hash": "9c6188da46f58639009a26f6848c90e714785bb0b89d8bb86ed44454209318a9", "code_hash": "c33a045aa16c202eacc6c195bdef5d88c24ac7df2e36a9d7f3172de7963b768d", diff --git a/.pdd/meta/commands_checkup_python.json b/.pdd/meta/commands_checkup_python.json index 896d30ae85..b72f5fad8d 100644 --- a/.pdd/meta/commands_checkup_python.json +++ b/.pdd/meta/commands_checkup_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.335452+00:00", + "timestamp": "2026-07-09T19:57:42.993476+00:00", "command": "test", "prompt_hash": "d42ff466ad8a19df7c2101a92e4b38737707e87ef7b59a64e77133a2c848a0b4", "code_hash": "0b7936aabeb40dd4eb0bde84d3693b8df3b5f423b3514b740b4fa4140a64ee6e", diff --git a/.pdd/meta/commands_checkup_simplify_python.json b/.pdd/meta/commands_checkup_simplify_python.json index 6f91aa0354..5626adfba1 100644 --- a/.pdd/meta/commands_checkup_simplify_python.json +++ b/.pdd/meta/commands_checkup_simplify_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.336126+00:00", + "timestamp": "2026-07-09T19:57:42.993915+00:00", "command": "fix", "prompt_hash": "879ba667d716fcf666ee1df507348749953d0dfba4e099fa0a9bac016945e101", "code_hash": "6ec8b1694b0ec8c9955261fff159b1a86397d54f24a0f95ea5243ac9cbd6df7f", diff --git a/.pdd/meta/commands_connect_python.json b/.pdd/meta/commands_connect_python.json index f21808451c..2f5bbe4d7f 100644 --- a/.pdd/meta/commands_connect_python.json +++ b/.pdd/meta/commands_connect_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.337357+00:00", + "timestamp": "2026-07-09T19:57:42.994895+00:00", "command": "fix", "prompt_hash": "a881214405113719a1009a1bd4ec2c340fbce3fa764c7d50a5e6965a7b5ef3b2", "code_hash": "f3a2c8d66a2f2555188a61a4828a5114bf1b99e6c2ebf19f84aef2b7da39cc5e", diff --git a/.pdd/meta/commands_context_python.json b/.pdd/meta/commands_context_python.json index c75fd15d12..07589887f8 100644 --- a/.pdd/meta/commands_context_python.json +++ b/.pdd/meta/commands_context_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.338066+00:00", + "timestamp": "2026-07-09T19:57:42.995522+00:00", "command": "fix", "prompt_hash": "e7351a988d749a910cd9dca718bb35d3a037a4a8fc75dd4211fb0e72f9b953cd", "code_hash": "3b67e44225298a9a76412cde3b8a933dad9e5a74be731453edf2e527bec5ee63", diff --git a/.pdd/meta/commands_contracts_python.json b/.pdd/meta/commands_contracts_python.json index 9fe4b58a73..cc6c919b02 100644 --- a/.pdd/meta/commands_contracts_python.json +++ b/.pdd/meta/commands_contracts_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.338427+00:00", + "timestamp": "2026-07-09T19:57:42.995917+00:00", "command": "fix", "prompt_hash": "ad58fc1a29f77c72d231a233db025de60a25c6509b030d198cdd77bed1e7d8cb", "code_hash": "cf070bb6670f4051aacf864306095707c581c6a48e57876d4d41d546fec5981c", diff --git a/.pdd/meta/commands_firecrawl_python.json b/.pdd/meta/commands_firecrawl_python.json index 190af2a51e..897978871b 100644 --- a/.pdd/meta/commands_firecrawl_python.json +++ b/.pdd/meta/commands_firecrawl_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.338790+00:00", + "timestamp": "2026-07-09T19:57:42.996310+00:00", "command": "fix", "prompt_hash": "e94170a1ab45cc700c6420a694f00624b4372d76a11746b6476162958e9de03a", "code_hash": "ef4b2875252e86550cbe6c87e07a3662edff352f87c3affdbf0393146833be7f", diff --git a/.pdd/meta/commands_fix_python.json b/.pdd/meta/commands_fix_python.json index 4390dfabb3..8455186a46 100644 --- a/.pdd/meta/commands_fix_python.json +++ b/.pdd/meta/commands_fix_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.339712+00:00", + "timestamp": "2026-07-09T19:57:42.997248+00:00", "command": "fix", "prompt_hash": "71d34c70ff508a726367285baaf296c9032b316bf81c5cbc97d6b900553d718a", "code_hash": "52a8eaa4c37566690f374fe5f596cf1d63762c8e68c1133985042d8571fd6543", diff --git a/.pdd/meta/commands_gate_python.json b/.pdd/meta/commands_gate_python.json index 21fced1039..07c3382846 100644 --- a/.pdd/meta/commands_gate_python.json +++ b/.pdd/meta/commands_gate_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.340071+00:00", + "timestamp": "2026-07-09T19:57:42.997616+00:00", "command": "fix", "prompt_hash": "55c2e3207298e63d0362345861747fe6711b18fd5f9f4acb9d6d73c821840542", "code_hash": "c75e65038098b8cbf57526c341028047c24f2813fcea2b3daeffe76bd1b57832", diff --git a/.pdd/meta/commands_generate_python.json b/.pdd/meta/commands_generate_python.json index 35bdd7dbb5..99d887e179 100644 --- a/.pdd/meta/commands_generate_python.json +++ b/.pdd/meta/commands_generate_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.341906+00:00", + "timestamp": "2026-07-09T19:57:42.999606+00:00", "command": "fix", "prompt_hash": "8192f9b9659b22fbfab38d99fa9d7d7316b582c0a365e28405e0d09c5d2c872c", "code_hash": "fc493964a405a7bc8444b131d27f98ca6af7cd08d569b99f09eb865a1eeae0b8", diff --git a/.pdd/meta/commands_maintenance_python.json b/.pdd/meta/commands_maintenance_python.json index a8be945a13..b17aaac543 100644 --- a/.pdd/meta/commands_maintenance_python.json +++ b/.pdd/meta/commands_maintenance_python.json @@ -1,16 +1,16 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.344275+00:00", + "timestamp": "2026-07-09T19:57:43.002009+00:00", "command": "fix", - "prompt_hash": "23aabe03f05d6759579e5a82ee07948b85f6c1db03e44ed417f577ac447cc9c6", - "code_hash": "2e6fc948c35d4ec0e3b9d08b1d3f53046ae9d3b80f9787cf7e0d29edc4ced5c9", + "prompt_hash": "d14964561101841448e50fc0181f7cc11f5b4db633e85d0791badda3b05e5abb", + "code_hash": "4fa2499fe14940b0bd6858ca665870236c8be4342b7d44514d920381616b980a", "example_hash": "89252d2bb50c54846397d3ec319aae9ce69434d2af7a6d746dd7d85a317216e6", - "test_hash": "87c5eb09a222437ac1dcccf4085993b870ea71af86f0077fff33292f17c37d00", + "test_hash": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a", "test_files": { - "test_maintenance.py": "87c5eb09a222437ac1dcccf4085993b870ea71af86f0077fff33292f17c37d00" + "test_maintenance.py": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/commands_misc_python.json b/.pdd/meta/commands_misc_python.json index 32d66d27cc..6275e0d919 100644 --- a/.pdd/meta/commands_misc_python.json +++ b/.pdd/meta/commands_misc_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.345532+00:00", + "timestamp": "2026-07-09T19:57:43.003193+00:00", "command": "fix", - "prompt_hash": "a2c00fc2b14606cb984ad67d1dc074edbe9899f6f07adc2cf99b6b0c2c31a57f", + "prompt_hash": "b975c6437984acbd35a0e88ea1eb17ef2a2477c3b5a18d600c8c0800c93584f7", "code_hash": "e49fff5cb806fc88e2ba5e54f445f2b2f855d6902946319c47a264ab6f13885c", "example_hash": "7d7985d21dd7b962257856cb92d13e26c016bc09ce14aaac4c68baaead97dc4b", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/preprocess_main_example.py": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/commands_modify_python.json b/.pdd/meta/commands_modify_python.json index 8ed83b0ff8..22872f0ee5 100644 --- a/.pdd/meta/commands_modify_python.json +++ b/.pdd/meta/commands_modify_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.347761+00:00", + "timestamp": "2026-07-09T19:57:43.005010+00:00", "command": "fix", "prompt_hash": "2f9a78de992e04c361ee0559f689b4c4b1f5d46f84ccf773ba208ebc0ea80a5b", "code_hash": "666d20da91b1037b24aa9a5c9f10684417ac31ad9c5c765c7b59d50916db7a99", diff --git a/.pdd/meta/commands_prompt_python.json b/.pdd/meta/commands_prompt_python.json index 1764d0c43b..d13216382c 100644 --- a/.pdd/meta/commands_prompt_python.json +++ b/.pdd/meta/commands_prompt_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.348411+00:00", + "timestamp": "2026-07-09T19:57:43.005410+00:00", "command": "test", "prompt_hash": "49253a7519e0deac37df0994c88519e0e4868e2c5420afd0fcf4eb89426e6583", "code_hash": "8c1e3e7d8dfaab47ee8c309c5fa7d3662b183807f5116dfd8e3d03aeba2adc6c", diff --git a/.pdd/meta/commands_replay_python.json b/.pdd/meta/commands_replay_python.json index cae8fdcc16..e075e2e62f 100644 --- a/.pdd/meta/commands_replay_python.json +++ b/.pdd/meta/commands_replay_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.349307+00:00", + "timestamp": "2026-07-09T19:57:43.005941+00:00", "command": "fix", "prompt_hash": "ac7765224d914a62041e86ed93be1e13fcab04bc1530083032596057e96f07ed", "code_hash": "6bb573b739993026c3aea2b3e47decd12420c33eb9932d7e7098058e600ff5b3", diff --git a/.pdd/meta/commands_report_python.json b/.pdd/meta/commands_report_python.json index 9b3aa00588..85f8e1665e 100644 --- a/.pdd/meta/commands_report_python.json +++ b/.pdd/meta/commands_report_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.350107+00:00", + "timestamp": "2026-07-09T19:57:43.006577+00:00", "command": "fix", "prompt_hash": "388398722a80945d1338eee36a96481e02911ec6d5e63e15a546a7d1dbe047b3", "code_hash": "c07ff974784d7f8f08b464e4326f6e22bb1250945411531dc3860cd7609f5c35", diff --git a/.pdd/meta/commands_sessions_python.json b/.pdd/meta/commands_sessions_python.json index 56937427c7..5daf9ef79b 100644 --- a/.pdd/meta/commands_sessions_python.json +++ b/.pdd/meta/commands_sessions_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.350965+00:00", + "timestamp": "2026-07-09T19:57:43.007296+00:00", "command": "fix", "prompt_hash": "cdfcedf57ee76527c398fbda65c5ee8050c523b3dcafb7c8ec8d0d65ea452422", "code_hash": "8b05a311e2ad2ef499eb6c97b4f68308f659f87976770181eb0b946a41012266", diff --git a/.pdd/meta/commands_story_python.json b/.pdd/meta/commands_story_python.json index 323954bcc4..95006480ce 100644 --- a/.pdd/meta/commands_story_python.json +++ b/.pdd/meta/commands_story_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.351702+00:00", + "timestamp": "2026-07-09T19:57:43.007947+00:00", "command": "fix", "prompt_hash": "8504142f3ab73f5beb85bc0f7bf5c5b92828bf54d1006e2c2cc6aa366a1cad7b", "code_hash": "a72c43090f69470d83fa4ec5836cd1528c9f8c8d98f063468833afb61030e736", diff --git a/.pdd/meta/commands_templates_python.json b/.pdd/meta/commands_templates_python.json index 2bd63dd44b..ecc5d2ae26 100644 --- a/.pdd/meta/commands_templates_python.json +++ b/.pdd/meta/commands_templates_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.352705+00:00", + "timestamp": "2026-07-09T19:57:43.008841+00:00", "command": "fix", - "prompt_hash": "f7452b0f2c022c68f5a2e522b6d2fe535cb081161c0515ba3593a9b1ceeb7e42", + "prompt_hash": "2b47f34b85744c82929e50eab832849b11ef2edf73a5ba17e5dd6c6ef9d789d7", "code_hash": "6cb72959c02bcb9df6c2661ed339d61a782f4466980c0f899371af2113818dd0", "example_hash": "017d7a9cbdec60dd67cee662f3b21a68638137cd086fb335ef92889e1d91b09a", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/commands_utility_python.json b/.pdd/meta/commands_utility_python.json index 1430aaa8c8..8840c5bba2 100644 --- a/.pdd/meta/commands_utility_python.json +++ b/.pdd/meta/commands_utility_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.354230+00:00", + "timestamp": "2026-07-09T19:57:43.010291+00:00", "command": "fix", - "prompt_hash": "3c02cfee56c2b08e75d0fedaba42a7f4246bf9d2a192f79a486da112c123d29c", + "prompt_hash": "d4329af7e4dd671fae0033c60e9feb6ae0470cc12c320c5072b153a31eee39ba", "code_hash": "9d0f70da4a91baf636335b69168fff3806b48d8fa6bc6bf0ca8c910bf1f11559", "example_hash": "fb7389c0ec837b8b6ee481e2eda04800f565fe247643f5bb9922dd1dfdab984a", "test_hash": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31", @@ -10,7 +10,7 @@ "test_utility.py": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/fix_verification_main_example.py": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", "context/install_completion_example.py": "999be17c0ce476845d7048a1a909ad425e60c298dbc7c74f51b596ef134a8aec", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/commands_which_python.json b/.pdd/meta/commands_which_python.json index a99965cd8b..65000f136c 100644 --- a/.pdd/meta/commands_which_python.json +++ b/.pdd/meta/commands_which_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.355005+00:00", + "timestamp": "2026-07-09T19:57:43.010933+00:00", "command": "fix", "prompt_hash": "2f3eac13978f6cbf66396d352071f00a3a670e81a6ca48206fa784aff9ae1882", "code_hash": "c36548d914d06d2c2b56c55b607249eaadb7c162cf1b1284d0377c79790214fa", diff --git a/.pdd/meta/comment_line_python.json b/.pdd/meta/comment_line_python.json index 686e0feca5..521e0f4a4d 100644 --- a/.pdd/meta/comment_line_python.json +++ b/.pdd/meta/comment_line_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.355358+00:00", + "timestamp": "2026-07-09T19:57:43.011213+00:00", "command": "fix", "prompt_hash": "f5012401ed39f35053deac030ea7bf5444c31b88a7d1380807895ecea0e0e6c4", "code_hash": "b17da17f86c6d5f20b8bfaef23d324930099d888ad80a916ee73a2c3c69028f6", diff --git a/.pdd/meta/compressed_sync_context_python.json b/.pdd/meta/compressed_sync_context_python.json index b90591131e..f496341511 100644 --- a/.pdd/meta/compressed_sync_context_python.json +++ b/.pdd/meta/compressed_sync_context_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.356507+00:00", + "timestamp": "2026-07-09T19:57:43.012294+00:00", "command": "fix", "prompt_hash": "c167d3127c74eab08bfd5a5293c8264e0582e777722fc47f0608b78bec5707ee", "code_hash": "661fde0fcc42ce39c1004e47a774a8fd799b789065519cb5688949c35fed4859", diff --git a/.pdd/meta/config_resolution_python.json b/.pdd/meta/config_resolution_python.json index ed16b0cafd..6ae73be539 100644 --- a/.pdd/meta/config_resolution_python.json +++ b/.pdd/meta/config_resolution_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.357030+00:00", + "timestamp": "2026-07-09T19:57:43.012951+00:00", "command": "fix", "prompt_hash": "f623b13d873302a7d13d94fe5d8556aa818f138dca71b4b8633dbce77bbbe030", "code_hash": "d50eb62241f36eed780d793a4631444f6f62e2551cff831e5c133f5dddc6a291", diff --git a/.pdd/meta/conflicts_in_prompts_python.json b/.pdd/meta/conflicts_in_prompts_python.json index 1d3bf9fc8f..e32ede0641 100644 --- a/.pdd/meta/conflicts_in_prompts_python.json +++ b/.pdd/meta/conflicts_in_prompts_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.357741+00:00", + "timestamp": "2026-07-09T19:57:43.013631+00:00", "command": "fix", "prompt_hash": "06501ee2b4c3a052873db04a0f3c8b629de39d655f665459591961d1e613fabc", "code_hash": "c0bd91a9575d399f8d95a428c1f96c227c4a85985ba3efc36e89c3b6d2e44c01", diff --git a/.pdd/meta/conflicts_main_python.json b/.pdd/meta/conflicts_main_python.json index 8e666717b3..97bce4900d 100644 --- a/.pdd/meta/conflicts_main_python.json +++ b/.pdd/meta/conflicts_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.358584+00:00", + "timestamp": "2026-07-09T19:57:43.014482+00:00", "command": "fix", "prompt_hash": "7a2bb8b334031ae46ded9dd01e1c0fa4cf4c68fc863dd33a347d36d0f95ea662", "code_hash": "63eb4e64da42e51be42ce4d691e6f4928753f99efd017359944a81ad114fc1be", diff --git a/.pdd/meta/construct_paths_python.json b/.pdd/meta/construct_paths_python.json index 74ade20208..62e021a416 100644 --- a/.pdd/meta/construct_paths_python.json +++ b/.pdd/meta/construct_paths_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.360478+00:00", + "timestamp": "2026-07-09T19:57:43.016103+00:00", "command": "fix", - "prompt_hash": "aa2c66e90540778ffe0df4ba14faeb39de2ea1b4e225ed21d88df36f92243607", + "prompt_hash": "239d02a86a003a736e6f857c05fe5a62e92b26e9147769aa7388c3d244f3fa3b", "code_hash": "7b42a002e4ecc27be4d517cbc07f1fc9425e795d4918714f382d2ed5ddd00eab", "example_hash": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "test_hash": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418", @@ -10,7 +10,7 @@ "test_construct_paths.py": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/generate_output_paths_example.py": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", diff --git a/.pdd/meta/content_selector_python.json b/.pdd/meta/content_selector_python.json index 0be6871b9b..26bd0bfbc9 100644 --- a/.pdd/meta/content_selector_python.json +++ b/.pdd/meta/content_selector_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.361320+00:00", + "timestamp": "2026-07-09T19:57:43.016921+00:00", "command": "fix", "prompt_hash": "584ea795707777378846cdcc413bbf1754ee3638d141878a4095c41a791b583b", "code_hash": "c18d5f9ce0903169445ee17d2e408b88ad91a931e710e783f7c9c7cc3f2ec4af", diff --git a/.pdd/meta/context_audit_python.json b/.pdd/meta/context_audit_python.json index 39575fdc37..70f7b3afda 100644 --- a/.pdd/meta/context_audit_python.json +++ b/.pdd/meta/context_audit_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.362163+00:00", + "timestamp": "2026-07-09T19:57:43.017807+00:00", "command": "fix", "prompt_hash": "8ddab8adfedeb2b501ae5df3b1989d446c13a72f64ea55668f62b75c605eff6d", "code_hash": "e9a2c33294a9045ed7eb93c4a4c53ae27added9e2b408619d7c5204386893b45", diff --git a/.pdd/meta/context_generator_main_python.json b/.pdd/meta/context_generator_main_python.json index 15e91cbcae..edc2b8e780 100644 --- a/.pdd/meta/context_generator_main_python.json +++ b/.pdd/meta/context_generator_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.364339+00:00", + "timestamp": "2026-07-09T19:57:43.019929+00:00", "command": "fix", "prompt_hash": "25d5bc7ab8ea0cc23287232060cb5d9d13b5523dcd5c2facaa84ac60d7d8fee1", "code_hash": "ea5831e4bafe49e056cc2d7e18be7b632f8de5752004bf08e66ebc4c82688c14", diff --git a/.pdd/meta/context_generator_python.json b/.pdd/meta/context_generator_python.json index 3406d6ac8f..dcb2a16ecb 100644 --- a/.pdd/meta/context_generator_python.json +++ b/.pdd/meta/context_generator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.365998+00:00", + "timestamp": "2026-07-09T19:57:43.021329+00:00", "command": "fix", "prompt_hash": "3417f94071a8113de24dbc9a3bbb393e85bd04a1b6fedd555ef0a1f39e57f164", "code_hash": "f972e2e2ce7444b7d3d186ab4540b8cad4f66dd0d97d37df00c58f32a9e3e369", diff --git a/.pdd/meta/context_snapshot_python.json b/.pdd/meta/context_snapshot_python.json index 441bbe849e..81fbee80d2 100644 --- a/.pdd/meta/context_snapshot_python.json +++ b/.pdd/meta/context_snapshot_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.366821+00:00", + "timestamp": "2026-07-09T19:57:43.021875+00:00", "command": "test", "prompt_hash": "d0da42dec926cca9da0b6ac499a2764830e30016e9a24f5749677a90fb976b3f", "code_hash": "6aa1ea0d41f73c40b02b72603f6193d4b6e51fdefb57d62f501311365a9ab1b8", diff --git a/.pdd/meta/continue_generation_python.json b/.pdd/meta/continue_generation_python.json index ed5c0f7cda..5987b83e9d 100644 --- a/.pdd/meta/continue_generation_python.json +++ b/.pdd/meta/continue_generation_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.367881+00:00", + "timestamp": "2026-07-09T19:57:43.022883+00:00", "command": "fix", "prompt_hash": "d8542e8a2dc3de4d0ceef1e16793504494e6827f58ded38b4944e6139d0b5a3c", "code_hash": "900b9e3385dbb947e4358357a58176cb9bc7a81e36bf8ac7cbada9ac6cf67e07", diff --git a/.pdd/meta/contract_check_python.json b/.pdd/meta/contract_check_python.json index d420f56032..16c6bd6bf1 100644 --- a/.pdd/meta/contract_check_python.json +++ b/.pdd/meta/contract_check_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.368400+00:00", + "timestamp": "2026-07-09T19:57:43.023353+00:00", "command": "fix", "prompt_hash": "31835ff8ff5462b9781926cf3b31b7c48ffccf56c338241ee55621fc2bfe9781", "code_hash": "5c168f2c45b6754acce9b7fd50730c1832053df160b5de88f064061333b84f1a", diff --git a/.pdd/meta/contract_ir_python.json b/.pdd/meta/contract_ir_python.json index 82da96acde..8bbd187595 100644 --- a/.pdd/meta/contract_ir_python.json +++ b/.pdd/meta/contract_ir_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.368822+00:00", + "timestamp": "2026-07-09T19:57:43.023737+00:00", "command": "fix", "prompt_hash": "92eb68b7fdc9a1b3fdb9c4f85ddc7e91d2aa9706c93da9915bd0b246dc792e24", "code_hash": "0d3392ec8990ac0ff6ddb4a00fee3c6719395f046a59a263ade7d8676e3648e9", diff --git a/.pdd/meta/core_cli_python.json b/.pdd/meta/core_cli_python.json index 40a41e53d1..6f33f980e0 100644 --- a/.pdd/meta/core_cli_python.json +++ b/.pdd/meta/core_cli_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.369721+00:00", + "timestamp": "2026-07-09T19:57:43.024586+00:00", "command": "fix", "prompt_hash": "172c853810b5b5005c10461da3014d38eea67f70fef2c3a6312eeac96eae8553", "code_hash": "fbdda9757fb6a4fd4be14ac670d4d79a3d2fdcc145ba1623fa63f85c1f6d7afa", diff --git a/.pdd/meta/core_cloud_python.json b/.pdd/meta/core_cloud_python.json index 0311f131ca..04271d2758 100644 --- a/.pdd/meta/core_cloud_python.json +++ b/.pdd/meta/core_cloud_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.370854+00:00", + "timestamp": "2026-07-09T19:57:43.025634+00:00", "command": "regenerate-public", "prompt_hash": "6055e3d124f3f4d5af83ec67ece60ee2653e0522f01e215d2b3c6f68dabceba8", "code_hash": "0487c0b989996af144df3af1c818a6eeafe52fd209710e5a54eb43990c89ae97", diff --git a/.pdd/meta/core_dump_python.json b/.pdd/meta/core_dump_python.json index 310f7a9b76..59b9ed778e 100644 --- a/.pdd/meta/core_dump_python.json +++ b/.pdd/meta/core_dump_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.371859+00:00", + "timestamp": "2026-07-09T19:57:43.026580+00:00", "command": "fix", - "prompt_hash": "ba2ac1af773b8c0e92594e6929fae405b34369a2e79d05f9bf5ab16e5a59b309", + "prompt_hash": "900d668f4ea02ae20cf5b3d9dbc3c34ff813ae02c7375cf705270f9c5360f33e", "code_hash": "16e6786e459f4d82e38e909fa93ce5eef7b6b4284eef6dcaa3bab99f21406421", "example_hash": "0416a935ac490b958ceedfc6e68c7fbd7e383966374ba13ccf7ebfeaf8ad0803", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_duplicate_cli_guard_python.json b/.pdd/meta/core_duplicate_cli_guard_python.json index 9f9cc290a8..41109185db 100644 --- a/.pdd/meta/core_duplicate_cli_guard_python.json +++ b/.pdd/meta/core_duplicate_cli_guard_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.373136+00:00", + "timestamp": "2026-07-09T19:57:43.027948+00:00", "command": "fix", "prompt_hash": "f041d7a7d8825a0f61eba4f523cfe32cd71089dfeb4db7831b1b8e99280b7451", "code_hash": "26ff24c97640c5818897f00cc5648708ffc719d6d7f113d24551662b9d724141", diff --git a/.pdd/meta/core_errors_python.json b/.pdd/meta/core_errors_python.json index 2a4aae2601..8cc7e849cb 100644 --- a/.pdd/meta/core_errors_python.json +++ b/.pdd/meta/core_errors_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.374044+00:00", + "timestamp": "2026-07-09T19:57:43.029130+00:00", "command": "fix", - "prompt_hash": "194ae5da34a2e913c0ab79597260d30f58f1efcf96f221ba73191fcc8ce898e4", + "prompt_hash": "a4ed232076bf25996465aa91044edf73bde1a63d99fce6a4bf7c0dffb4fd3a39", "code_hash": "fee544cef7641ad0b326790a4e90cc9d662a4bfcb01fac75aeb910ff85e56b84", "example_hash": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_remote_session_python.json b/.pdd/meta/core_remote_session_python.json index 9196091386..ac949676a2 100644 --- a/.pdd/meta/core_remote_session_python.json +++ b/.pdd/meta/core_remote_session_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.374470+00:00", + "timestamp": "2026-07-09T19:57:43.029586+00:00", "command": "fix", "prompt_hash": "cbfe9e8449a09296501889ea92a9a2cae7b5743592ad2632b139e5423c1bab77", "code_hash": "163292e0200246767f685e9478c8ab4531c06ba471be4ceb9a6ee8065b1cfc12", diff --git a/.pdd/meta/core_utils_python.json b/.pdd/meta/core_utils_python.json index 99e3e205a9..96c94304a0 100644 --- a/.pdd/meta/core_utils_python.json +++ b/.pdd/meta/core_utils_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.375386+00:00", + "timestamp": "2026-07-09T19:57:43.030505+00:00", "command": "fix", - "prompt_hash": "24a3f952031edaa22704f965c69225836e65dc4827a838775d17e7728f181bc8", + "prompt_hash": "15b54fe34d3a28284b7a3c85a6afe06db0ba142849488d26bb7a29dafe06c498", "code_hash": "4386b3c9efd08ba0510aa80150b579f203fe9dbc32e047712599a34f55537191", "example_hash": "ecda9cd9c5910246e0f857eacacac6ec381eb531695e5a56670a9dd8c02c0ef1", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/coverage_contracts_python.json b/.pdd/meta/coverage_contracts_python.json index 3eb7041b78..1a14ee8325 100644 --- a/.pdd/meta/coverage_contracts_python.json +++ b/.pdd/meta/coverage_contracts_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.375769+00:00", + "timestamp": "2026-07-09T19:57:43.030870+00:00", "command": "fix", "prompt_hash": "044980f2b8fe2bd1c0a3c294322b4e8767d9f12f8bb24410ba6e4ed818465dd8", "code_hash": "dc209452c683697866e133c5673a2caba1828c9e4836e012f277e0250a643c0c", diff --git a/.pdd/meta/crash_main_python.json b/.pdd/meta/crash_main_python.json index 035895357e..db8da6f284 100644 --- a/.pdd/meta/crash_main_python.json +++ b/.pdd/meta/crash_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.376863+00:00", + "timestamp": "2026-07-09T19:57:43.031818+00:00", "command": "fix", "prompt_hash": "a2b233c48783a94be5b4e746a8267b114a0198702ed0f69e0357fc9b8164508d", "code_hash": "bab5a25767957060eded0b59efc275da7f76acc173a23ec943c08a36c4eb2764", diff --git a/.pdd/meta/detect_change_main_python.json b/.pdd/meta/detect_change_main_python.json index 005d6cc3ac..4eac945f8b 100644 --- a/.pdd/meta/detect_change_main_python.json +++ b/.pdd/meta/detect_change_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.378309+00:00", + "timestamp": "2026-07-09T19:57:43.033191+00:00", "command": "fix", - "prompt_hash": "1e20741ae1a6daf3aaa48ab3ea0a245c9e463b503234fef18a0c5343ab39729b", + "prompt_hash": "4ce30e6306826a9e7e754287f8c7b5a3c78b18efa5a7e3035fbffe2ece13d63a", "code_hash": "2ef7a1859b4195c37e441c7ec79c00cfdff81f68af80dc277a4ee88b586d923a", "example_hash": "ddc494709d127398004f53de58bede388692b2839a97b26668c55575369d9edd", "test_hash": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6", @@ -10,7 +10,7 @@ "test_detect_change_main.py": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", diff --git a/.pdd/meta/detect_change_python.json b/.pdd/meta/detect_change_python.json index 1a01cfbabd..f6e12a4d21 100644 --- a/.pdd/meta/detect_change_python.json +++ b/.pdd/meta/detect_change_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.380199+00:00", + "timestamp": "2026-07-09T19:57:43.035078+00:00", "command": "fix", "prompt_hash": "74aafd447bc746f4ea46fbd2bce19b9824803689714266c58f6724e31225ae61", "code_hash": "46a3bf79582e6f88dc13f23183c0a8a871cbcfc4fd7e6ef98fccb49e90ca908c", diff --git a/.pdd/meta/durable_sync_runner_python.json b/.pdd/meta/durable_sync_runner_python.json index 890da34317..dae9eedbdc 100644 --- a/.pdd/meta/durable_sync_runner_python.json +++ b/.pdd/meta/durable_sync_runner_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.381366+00:00", + "timestamp": "2026-07-09T19:57:43.036036+00:00", "command": "fix", "prompt_hash": "33674ac16f38437372bccd6d7b6d6b1c720528a4f6f4c358cfb78c34e2441ede", "code_hash": "9bf0265a38b57f44c5c5f9962d55d6f5e17792b6217cf5749d65c2e123985392", diff --git a/.pdd/meta/edit_file_python.json b/.pdd/meta/edit_file_python.json index 82d18e1799..01dcec301b 100644 --- a/.pdd/meta/edit_file_python.json +++ b/.pdd/meta/edit_file_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.381713+00:00", + "timestamp": "2026-07-09T19:57:43.036472+00:00", "command": "fix", "prompt_hash": "7617636b78e26e2ff2ab2840a087435689a14dda5e8a5e6304ff75af2c7a6364", "code_hash": "f85859f8a18a6243db9edd331620e79e8b0f2e1ddb6ca99fb5e9f4228b38fbdd", diff --git a/.pdd/meta/embed_retrieve_python.json b/.pdd/meta/embed_retrieve_python.json index 89b1da1074..13790305a8 100644 --- a/.pdd/meta/embed_retrieve_python.json +++ b/.pdd/meta/embed_retrieve_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.382194+00:00", + "timestamp": "2026-07-09T19:57:43.036919+00:00", "command": "fix", "prompt_hash": "555494744ac9cac860b021a4f122449a6a67be1a9388f23a7ac8ca47f0f47603", "code_hash": "86834b149d6112a05bd2b98f38878c4d967d0667e9722ed7ce43f5217f98729e", diff --git a/.pdd/meta/evidence_manifest_python.json b/.pdd/meta/evidence_manifest_python.json index 53c8770029..a9fc18ad73 100644 --- a/.pdd/meta/evidence_manifest_python.json +++ b/.pdd/meta/evidence_manifest_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.382671+00:00", + "timestamp": "2026-07-09T19:57:43.037404+00:00", "command": "fix", "prompt_hash": "272555690e7df823d17bb5729d7f2ae871b27af13aa4109c533e3c9dbd289792", "code_hash": "8f468855a9a9f997b73147b37cf937d1594dacf147c7e2ec34565099a9f1e40b", diff --git a/.pdd/meta/evidence_store_python.json b/.pdd/meta/evidence_store_python.json index 230fbcbfd5..4273944f55 100644 --- a/.pdd/meta/evidence_store_python.json +++ b/.pdd/meta/evidence_store_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.383026+00:00", + "timestamp": "2026-07-09T19:57:43.037754+00:00", "command": "fix", "prompt_hash": "5083989f11139a52428b6b58b8f6d9126d4aa75afd54a0af03d3a676ec73dc69", "code_hash": "eccc499c6f076b52e4b481a07904b9390120e52c49cb2479adbdf5eb433df14c", diff --git a/.pdd/meta/extracts_prune_python.json b/.pdd/meta/extracts_prune_python.json index 8b9ed55d5e..7e8e8e2a72 100644 --- a/.pdd/meta/extracts_prune_python.json +++ b/.pdd/meta/extracts_prune_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.383898+00:00", + "timestamp": "2026-07-09T19:57:43.038583+00:00", "command": "fix", "prompt_hash": "1c1743a61d7690b35115be3fbabbaa5bc55e1268b74efa7b0af5ce782f29c571", "code_hash": "0bc2ebd73806ce23453c8b97a763891a8c045c3d9214edd0a719b8fc328c0a06", diff --git a/.pdd/meta/failure_classification_python.json b/.pdd/meta/failure_classification_python.json index eaf25994a1..ac48180c12 100644 --- a/.pdd/meta/failure_classification_python.json +++ b/.pdd/meta/failure_classification_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.384471+00:00", + "timestamp": "2026-07-09T19:57:43.038998+00:00", "command": "fix", "prompt_hash": "f4a1ca1b51cb57f7c8513109c6f17e181045166075daf11d973d31cc495af816", "code_hash": "0675857d23f52e447f15ace22ec37c2f003a61d3c810254c8547129c29d697ff", diff --git a/.pdd/meta/find_section_python.json b/.pdd/meta/find_section_python.json index 44d5feae90..991e7e9685 100644 --- a/.pdd/meta/find_section_python.json +++ b/.pdd/meta/find_section_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.384903+00:00", + "timestamp": "2026-07-09T19:57:43.039316+00:00", "command": "fix", "prompt_hash": "30b22c834c4a659be69878bef0d3cea6f7cf75c93e6dc9f3e585a7a4cbb564b5", "code_hash": "973fc53d8e0a0c24401a52f5a565598aeb5436fec4e0ab0314afb2983580fc47", diff --git a/.pdd/meta/firecrawl_cache_python.json b/.pdd/meta/firecrawl_cache_python.json index c6be84faee..8832b399d2 100644 --- a/.pdd/meta/firecrawl_cache_python.json +++ b/.pdd/meta/firecrawl_cache_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.385405+00:00", + "timestamp": "2026-07-09T19:57:43.039734+00:00", "command": "fix", "prompt_hash": "1b8c25255fc1387765e986b0775379102e71c71c7e0b90076c65822992162894", "code_hash": "4b5ffcf7246451bf1c60f86594dda44e4eeeb89778a56e0a400ba35dd17e1677", diff --git a/.pdd/meta/fix_code_loop_python.json b/.pdd/meta/fix_code_loop_python.json index 26bef435ab..c80982d1f8 100644 --- a/.pdd/meta/fix_code_loop_python.json +++ b/.pdd/meta/fix_code_loop_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.386504+00:00", + "timestamp": "2026-07-09T19:57:43.040788+00:00", "command": "regenerate-public", "prompt_hash": "6a32dcc711f1e24de6b23d4a498bd00b1d41ab058d4fd64dfc3b76ea42d8dc94", "code_hash": "3bff0fb82111513ed5aa32c33bd80578c7178e871f818be1b01635b7a2b185b1", diff --git a/.pdd/meta/fix_code_module_errors_python.json b/.pdd/meta/fix_code_module_errors_python.json index 9b6edce134..7b303744b5 100644 --- a/.pdd/meta/fix_code_module_errors_python.json +++ b/.pdd/meta/fix_code_module_errors_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.387188+00:00", + "timestamp": "2026-07-09T19:57:43.041472+00:00", "command": "fix", "prompt_hash": "67f31fdf9d727abafe85503ac9aacc3043e1373bd87893ee97d91bbe7fcf3807", "code_hash": "cdb5b1681cc0629f6bd28c19be5378e9a005280d606723a366a5fabc2133ed89", diff --git a/.pdd/meta/fix_error_loop_python.json b/.pdd/meta/fix_error_loop_python.json index 47c0a01eed..d5d4bc7018 100644 --- a/.pdd/meta/fix_error_loop_python.json +++ b/.pdd/meta/fix_error_loop_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.389414+00:00", + "timestamp": "2026-07-09T19:57:43.043621+00:00", "command": "example", "prompt_hash": "ae052bd412593cd6bf368c6aa753852f19b7698162713431ca0e054e0b7d9c3f", "code_hash": "8454d9d818cbc14e80f15b8d79fd790279bcdfb31bbb68b84a0611b99396c0c6", diff --git a/.pdd/meta/fix_errors_from_unit_tests_python.json b/.pdd/meta/fix_errors_from_unit_tests_python.json index f5ae7d1db8..ab614dd844 100644 --- a/.pdd/meta/fix_errors_from_unit_tests_python.json +++ b/.pdd/meta/fix_errors_from_unit_tests_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.391388+00:00", + "timestamp": "2026-07-09T19:57:43.045611+00:00", "command": "fix", "prompt_hash": "5dd9132474b83ac80334bfeefdfc55478d506da9d95acd54ddbbca97c00995a6", "code_hash": "7ad19b3ca4b61406c1da5dcd86783a5b1aa183f9ecea231979675de6f3924404", diff --git a/.pdd/meta/fix_focus_python.json b/.pdd/meta/fix_focus_python.json index d6b2073e5b..ef01dfd1a4 100644 --- a/.pdd/meta/fix_focus_python.json +++ b/.pdd/meta/fix_focus_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.392102+00:00", + "timestamp": "2026-07-09T19:57:43.046496+00:00", "command": "fix", "prompt_hash": "5495f47b8ca32f768f25b4864a4a6bd59daae7ac21544c4ae75363e0ca6d2ee4", "code_hash": "e341e6bda871ddc5ba92cf05e9d554d49bc5e4afebf5b4f1482971edf557063d", diff --git a/.pdd/meta/fix_main_python.json b/.pdd/meta/fix_main_python.json index 17bfd0fa49..4bcfd671d6 100644 --- a/.pdd/meta/fix_main_python.json +++ b/.pdd/meta/fix_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.393900+00:00", + "timestamp": "2026-07-09T19:57:43.048358+00:00", "command": "fix", "prompt_hash": "aa3e9b550afbcdb9e95e2c92fddf04111709b422649cb3266e728fa8b5a38652", "code_hash": "3f67d418500e2ec32d016c3ec50bce459e8fa05e75711b46d2a38e683347a60f", diff --git a/.pdd/meta/fix_verification_errors_loop_python.json b/.pdd/meta/fix_verification_errors_loop_python.json index d992bb87e0..3e7ccab9d6 100644 --- a/.pdd/meta/fix_verification_errors_loop_python.json +++ b/.pdd/meta/fix_verification_errors_loop_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.395075+00:00", + "timestamp": "2026-07-09T19:57:43.049504+00:00", "command": "fix", "prompt_hash": "3afa1fd7d8e92ad9a2d6a5f20468ade73a9ea077adb8a01fb2dba1583cde6086", "code_hash": "ea1649f2cafd6e7eb7db3f19489d7ac0bcc96137b9b73291b6720ba4fb38341f", diff --git a/.pdd/meta/fix_verification_errors_python.json b/.pdd/meta/fix_verification_errors_python.json index 512d698f38..dc297dd208 100644 --- a/.pdd/meta/fix_verification_errors_python.json +++ b/.pdd/meta/fix_verification_errors_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.396030+00:00", + "timestamp": "2026-07-09T19:57:43.050450+00:00", "command": "fix", "prompt_hash": "65f5c3f6032927203ab5722359e8b1c0ab326708dde9483408fc1c77fd85a683", "code_hash": "5abede2b80b05cb859c83d41618c1e5bebddabfecddf7501042a9f09526fcefa", diff --git a/.pdd/meta/fix_verification_main_python.json b/.pdd/meta/fix_verification_main_python.json index c13321a95b..26b70d04d6 100644 --- a/.pdd/meta/fix_verification_main_python.json +++ b/.pdd/meta/fix_verification_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.397083+00:00", + "timestamp": "2026-07-09T19:57:43.051467+00:00", "command": "fix", "prompt_hash": "d6577292faee7ad7513ead07332c24f2a836d0b1bb8793064004d7549e240d41", "code_hash": "42b18d666938c41e9ee58b08cfec349de715da44ace4f5e2987bc9d725f4a089", diff --git a/.pdd/meta/gate_policy_python.json b/.pdd/meta/gate_policy_python.json index c81c70d736..89eb27456c 100644 --- a/.pdd/meta/gate_policy_python.json +++ b/.pdd/meta/gate_policy_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.397448+00:00", + "timestamp": "2026-07-09T19:57:43.051827+00:00", "command": "fix", "prompt_hash": "d489b706b3b826e8e18bba5d945a97aaa8abca83728afffcd91bd9a51b83da40", "code_hash": "110ad068b2e5f1d4c0aa0e8ace3c8da8acb05d48f3116b6229459ed258d69667", diff --git a/.pdd/meta/generate_model_catalog_python.json b/.pdd/meta/generate_model_catalog_python.json index b5e181ade1..b7a3f829ac 100644 --- a/.pdd/meta/generate_model_catalog_python.json +++ b/.pdd/meta/generate_model_catalog_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.397933+00:00", + "timestamp": "2026-07-09T19:57:43.052285+00:00", "command": "fix", "prompt_hash": "1e0ffc1fb8e8172bb396b8050c67bfbf750e28bd4191ffb63f7d664d0530827e", "code_hash": "2c3ede9cb5b9ab319af0b7c950309a1fc0cb620a0555cef6b427b004fce1a353", diff --git a/.pdd/meta/generate_output_paths_python.json b/.pdd/meta/generate_output_paths_python.json index ded311533a..17414d571f 100644 --- a/.pdd/meta/generate_output_paths_python.json +++ b/.pdd/meta/generate_output_paths_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.399220+00:00", + "timestamp": "2026-07-09T19:57:43.053869+00:00", "command": "fix", - "prompt_hash": "e71a805eb795dfbc6f31f06b5f521521ff4a7a93adce9dce95c788df49c69711", + "prompt_hash": "1e95a6b815495f5ffadd61e9bc5b36db6b47cb5d89f1c7a7b25ee89a7a13a751", "code_hash": "13890fe1983e3554b58f67404ce3848b3e9e329c03cf661446ad9ef62a71b43e", "example_hash": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "test_hash": "c0ed9c8db22f119f3849ee3e00d8bac35b8d67fc78dfcccc5d6fefc78d1f081a", @@ -11,7 +11,7 @@ "test_generate_output_paths_regression.py": "3763968e8dc0e661e6516520f9282776ae81f82d5207633926ccee6fd60d50ba" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74" } diff --git a/.pdd/meta/generate_test_python.json b/.pdd/meta/generate_test_python.json index f1bffaa536..9a16c3b1be 100644 --- a/.pdd/meta/generate_test_python.json +++ b/.pdd/meta/generate_test_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.401706+00:00", + "timestamp": "2026-07-09T19:57:43.056523+00:00", "command": "fix", "prompt_hash": "c77e5b4722100e72acb3addac1f9f2cd4e87cecc314f9ff4e984314b3d21eff6", "code_hash": "c34164ec5abded5fbc0e600f3ad007fc6175a29d0662dded3d57edbae9e3fb17", diff --git a/.pdd/meta/generation_completion_python.json b/.pdd/meta/generation_completion_python.json index 52fc6123be..cb13c479c9 100644 --- a/.pdd/meta/generation_completion_python.json +++ b/.pdd/meta/generation_completion_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.402113+00:00", + "timestamp": "2026-07-09T19:57:43.056922+00:00", "command": "fix", "prompt_hash": "dde7e344d8f08e298359f9ef72e7b38c0badc58c47d5d1162d51a60601808fcf", "code_hash": "8313db548a81def2265688d325e532fd1a44ac1f45c1cf65f534b15887b012b9", diff --git a/.pdd/meta/get_comment_python.json b/.pdd/meta/get_comment_python.json index d164d68fbc..4f9e1dc632 100644 --- a/.pdd/meta/get_comment_python.json +++ b/.pdd/meta/get_comment_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.402627+00:00", + "timestamp": "2026-07-09T19:57:43.057399+00:00", "command": "regenerate-public", "prompt_hash": "8ed03ff72edaea977592d8c37140fddb51fe19866589dfd9d2b5d0fcdbde5420", "code_hash": "53e70fe3e4f7ba637f7c754d95a751e068754eb06d265b1e95636349c118a883", diff --git a/.pdd/meta/get_extension_python.json b/.pdd/meta/get_extension_python.json index b2cc498f6c..9e86d8f72f 100644 --- a/.pdd/meta/get_extension_python.json +++ b/.pdd/meta/get_extension_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.403182+00:00", + "timestamp": "2026-07-09T19:57:43.057987+00:00", "command": "fix", "prompt_hash": "8cc4693dd0372bc8971b7e4902618a975fca012d410d403cb36b174ee2dea8c1", "code_hash": "4f9ab4599944c8faf14fb060f83a0b6745d1d096b357de34b21c3b34a84480d7", diff --git a/.pdd/meta/get_jwt_token_python.json b/.pdd/meta/get_jwt_token_python.json index 64302fb086..dfa0d154f3 100644 --- a/.pdd/meta/get_jwt_token_python.json +++ b/.pdd/meta/get_jwt_token_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.403914+00:00", + "timestamp": "2026-07-09T19:57:43.058869+00:00", "command": "fix", "prompt_hash": "7a311e6892810f02d38a2482ee1f42cf0f5f575a394f0de2518baf4a3c45c304", "code_hash": "93f690a01f9945f8c7434b48c52e3548764275b99c933e8952c7bf5f0a3b4316", diff --git a/.pdd/meta/get_language_python.json b/.pdd/meta/get_language_python.json index 28e6e48a5b..292cda19c3 100644 --- a/.pdd/meta/get_language_python.json +++ b/.pdd/meta/get_language_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.404417+00:00", + "timestamp": "2026-07-09T19:57:43.059435+00:00", "command": "fix", "prompt_hash": "342a9c09594784c2199ab87d52dd03e6d8b27a220c219d121b08b28efaf8c444", "code_hash": "65004add40c93365c1cbd705a6ef24d5bda6f7016c3a67749b25e61122c50ce7", diff --git a/.pdd/meta/get_lint_commands_python.json b/.pdd/meta/get_lint_commands_python.json index 4268459215..991151d865 100644 --- a/.pdd/meta/get_lint_commands_python.json +++ b/.pdd/meta/get_lint_commands_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.404998+00:00", + "timestamp": "2026-07-09T19:57:43.060011+00:00", "command": "fix", "prompt_hash": "099f72e088fc18213c08338f23a33750ac07da246ee38b2449fe7875c46dc1ce", "code_hash": "3f48c9f1d209d09754f53f07c6196288ae8ff0e239e8020f4b370ddf36285f45", diff --git a/.pdd/meta/get_run_command_python.json b/.pdd/meta/get_run_command_python.json index eaa6676680..21c196bab6 100644 --- a/.pdd/meta/get_run_command_python.json +++ b/.pdd/meta/get_run_command_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.405577+00:00", + "timestamp": "2026-07-09T19:57:43.060580+00:00", "command": "fix", "prompt_hash": "8ca93563bceca5fb9462c5cee01eb969f1c56d6bd162206a10ff0d953fd6cb78", "code_hash": "5eec778a234abc4ace4166d71a68f6e49f1b81491962867de81f61be882a5319", diff --git a/.pdd/meta/get_test_command_python.json b/.pdd/meta/get_test_command_python.json index 07cbfec6d2..f78cbcd66a 100644 --- a/.pdd/meta/get_test_command_python.json +++ b/.pdd/meta/get_test_command_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.406672+00:00", + "timestamp": "2026-07-09T19:57:43.061458+00:00", "command": "regenerate-public", "prompt_hash": "ba7e479e5f8a3344d1e5f1694701fb6158e7ee8193b26576a5b459334e8bc683", "code_hash": "a1e871896a289049c73df4071ec48fc47792ff6cab05332816ba702cd3bc1cb6", diff --git a/.pdd/meta/git_porcelain_python.json b/.pdd/meta/git_porcelain_python.json index fa093e3eef..c3ef7a5f03 100644 --- a/.pdd/meta/git_porcelain_python.json +++ b/.pdd/meta/git_porcelain_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.407159+00:00", + "timestamp": "2026-07-09T19:57:43.061876+00:00", "command": "fix", "prompt_hash": "2c95a26de29ea34f2c2f0386acc109026889e316b12e7573fcdfce342907459a", "code_hash": "b10bbce7f1bb04079472bf76c36a4aef208bdf497a8922af224a69cb16717814", diff --git a/.pdd/meta/git_update_python.json b/.pdd/meta/git_update_python.json index 8ca2b2bf4b..a7b87127f0 100644 --- a/.pdd/meta/git_update_python.json +++ b/.pdd/meta/git_update_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.407926+00:00", + "timestamp": "2026-07-09T19:57:43.062581+00:00", "command": "regenerate-public", "prompt_hash": "0aca4d865e12f462ee930a445fbd8d376bde2efa0ba9a5a6b57877d80f91f714", "code_hash": "ca810925f80b85596c0f1f84b4a7c052ff19a8530d24ed6989730467df2a3f17", diff --git a/.pdd/meta/grounding_policy_python.json b/.pdd/meta/grounding_policy_python.json index fa460ef377..2dd62e2ac4 100644 --- a/.pdd/meta/grounding_policy_python.json +++ b/.pdd/meta/grounding_policy_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.408337+00:00", + "timestamp": "2026-07-09T19:57:43.062981+00:00", "command": "fix", "prompt_hash": "e9ff88e848dcdcd473657d892478bacf4ab76c09f39378cb6a3d3a43578db91d", "code_hash": "76dfda96180a84f8efaa3836ed4a5b4fccaf16f69d12c72006d4ec89529e8cca", diff --git a/.pdd/meta/include_query_extractor_python.json b/.pdd/meta/include_query_extractor_python.json index 625961bcf3..e9e3ddec07 100644 --- a/.pdd/meta/include_query_extractor_python.json +++ b/.pdd/meta/include_query_extractor_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.409908+00:00", + "timestamp": "2026-07-09T19:57:43.064656+00:00", "command": "fix", "prompt_hash": "369d47b3113a0645885716e99e00eb6474834b38a91e30fa30b7625d53afcf0b", "code_hash": "fa95489a0b7b8f3ad6e887844fe14f38350e56b3d2fc2e4add08318334bcd191", diff --git a/.pdd/meta/increase_tests_python.json b/.pdd/meta/increase_tests_python.json index 39ddbd6a6c..ba8adcd885 100644 --- a/.pdd/meta/increase_tests_python.json +++ b/.pdd/meta/increase_tests_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.410722+00:00", + "timestamp": "2026-07-09T19:57:43.065554+00:00", "command": "fix", "prompt_hash": "ae3160a949d20da81e12d62a0129c1b8e3b0d7b2073c97536d25cfd258a94abe", "code_hash": "ebc70cf5dd42a5a2cb9b6212169270dfdc5b463b1fc31c12d3ac80c11a140879", diff --git a/.pdd/meta/incremental_code_generator_python.json b/.pdd/meta/incremental_code_generator_python.json index b66ee1c021..730ad886be 100644 --- a/.pdd/meta/incremental_code_generator_python.json +++ b/.pdd/meta/incremental_code_generator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.411982+00:00", + "timestamp": "2026-07-09T19:57:43.066582+00:00", "command": "fix", "prompt_hash": "e2bfbfc77a1dee1e4b393a6f9b377de31f07b6a0ab2693153455366467180b1b", "code_hash": "8dd5dd7f3016b8fae86056484fdc49b824405cdcd6911e8b8657d3e043b3b06d", diff --git a/.pdd/meta/incremental_prd_architecture_python.json b/.pdd/meta/incremental_prd_architecture_python.json index e7cf1c9702..993d9e596c 100644 --- a/.pdd/meta/incremental_prd_architecture_python.json +++ b/.pdd/meta/incremental_prd_architecture_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.413146+00:00", + "timestamp": "2026-07-09T19:57:43.067742+00:00", "command": "fix", "prompt_hash": "1d30710eab8191e5a651513484774f60603091ccc97fa9518ec2aef35b1d5a49", "code_hash": "96f56cca2ab0ce86ec389e77057421d9d972d9fff9b937d60fcca92aac6adf9b", diff --git a/.pdd/meta/insert_includes_python.json b/.pdd/meta/insert_includes_python.json index e2275899fd..d4934dcc5a 100644 --- a/.pdd/meta/insert_includes_python.json +++ b/.pdd/meta/insert_includes_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.414436+00:00", + "timestamp": "2026-07-09T19:57:43.069273+00:00", "command": "fix", "prompt_hash": "c91a10b91e1df2f4fa1d8cce5fb3e3a98b7632497153c9f181a20c77df00a4c7", "code_hash": "6aaac12e5b791d63a1223d711a89b49e1d7eba4eb6dbf60c2273c608c6c73307", diff --git a/.pdd/meta/install_completion_python.json b/.pdd/meta/install_completion_python.json index c5b454b917..b60bcf2306 100644 --- a/.pdd/meta/install_completion_python.json +++ b/.pdd/meta/install_completion_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.415176+00:00", + "timestamp": "2026-07-09T19:57:43.069932+00:00", "command": "fix", "prompt_hash": "195b5686fa2baa0e4c63549f75ebc9e7bb7eaeeec3b9f32a9043c3fc202c506e", "code_hash": "6cb309b8c3810efb049c3014a6088f7ac3511a163f22f06fcfc66f99b4f33f8a", diff --git a/.pdd/meta/llm_invoke_python.json b/.pdd/meta/llm_invoke_python.json index 9a700a1a75..bb76f85b67 100644 --- a/.pdd/meta/llm_invoke_python.json +++ b/.pdd/meta/llm_invoke_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.417870+00:00", + "timestamp": "2026-07-09T19:57:43.072390+00:00", "command": "test", "prompt_hash": "41404dff8babe6a1ff78b29f7ada4a173fcba6d8b3e0f6248c949716992d1dd2", "code_hash": "2c423dbe12dd22d1acfca6c658bfef36eaf3b016626ae4a2845576500bfcb54b", diff --git a/.pdd/meta/load_prompt_template_python.json b/.pdd/meta/load_prompt_template_python.json index 110e33787d..f121e277c6 100644 --- a/.pdd/meta/load_prompt_template_python.json +++ b/.pdd/meta/load_prompt_template_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.418356+00:00", + "timestamp": "2026-07-09T19:57:43.073164+00:00", "command": "fix", "prompt_hash": "7621531d40ff40acbc0088160d6e48b959b88afca9dd461258c56a57ec1b42a2", "code_hash": "903bb43e90d778fa04ba42cd8e329ac42e1b419bb372268f5955f26de43cce47", diff --git a/.pdd/meta/logo_animation_python.json b/.pdd/meta/logo_animation_python.json index 6bfee44f19..44edb4ac14 100644 --- a/.pdd/meta/logo_animation_python.json +++ b/.pdd/meta/logo_animation_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.418883+00:00", + "timestamp": "2026-07-09T19:57:43.073735+00:00", "command": "fix", "prompt_hash": "f0724c74377388bfb72c6b9fb4877b65990a9cf88e7a1fa5fbdabdf3c3860a36", "code_hash": "9fa1c95b3b85cded9cb00016dbecdbc5f8ef585611238848770541b4704e923e", diff --git a/.pdd/meta/metadata_sync_python.json b/.pdd/meta/metadata_sync_python.json index 5ed74e2508..914f7f71dc 100644 --- a/.pdd/meta/metadata_sync_python.json +++ b/.pdd/meta/metadata_sync_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.420359+00:00", + "timestamp": "2026-07-09T19:57:43.075226+00:00", "command": "fix", "prompt_hash": "8ccd27574100139772388c34fcab32fbae253154d449f1ffeead270d6c92dc8d", "code_hash": "3afaa5a409e500b3f91aab33dacee33fae47447fba80a1702d65a33761261782", diff --git a/.pdd/meta/model_tester_python.json b/.pdd/meta/model_tester_python.json index cc02f86864..d970677033 100644 --- a/.pdd/meta/model_tester_python.json +++ b/.pdd/meta/model_tester_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.420905+00:00", + "timestamp": "2026-07-09T19:57:43.075713+00:00", "command": "fix", "prompt_hash": "fd82b8c71a0ba03c664946897f00c969643ee2fe846a001a02c560c9d2003327", "code_hash": "786ac21e50a29087e035af7fbbfeac05e3fc2930ec3d4916ca73774623da5384", diff --git a/.pdd/meta/one_session_sync_python.json b/.pdd/meta/one_session_sync_python.json index 730ecfe632..e2cac2642f 100644 --- a/.pdd/meta/one_session_sync_python.json +++ b/.pdd/meta/one_session_sync_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.423139+00:00", + "timestamp": "2026-07-09T19:57:43.077832+00:00", "command": "fix", "prompt_hash": "d63a4299e9dbdaf43a74f14160a021b7e31be6403eb041fe8383b429ca6ffe11", "code_hash": "37541cc02ed9eae748f2270beb39c5a66bf098bac87bf757a3e00e382d41fcf2", diff --git a/.pdd/meta/operation_log_python.json b/.pdd/meta/operation_log_python.json index db8320771c..c69ed8987a 100644 --- a/.pdd/meta/operation_log_python.json +++ b/.pdd/meta/operation_log_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.423839+00:00", + "timestamp": "2026-07-09T19:57:43.078440+00:00", "command": "fix", "prompt_hash": "d09eedd7f6b781864544d62c7f513b760a3e418b3cd29efa738a4b0ddedc52ed", "code_hash": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", diff --git a/.pdd/meta/path_resolution_python.json b/.pdd/meta/path_resolution_python.json index 02ad88e3ff..38b9e1d1f5 100644 --- a/.pdd/meta/path_resolution_python.json +++ b/.pdd/meta/path_resolution_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.424308+00:00", + "timestamp": "2026-07-09T19:57:43.079223+00:00", "command": "fix", "prompt_hash": "17ed2dc0cc1541e5267c988065f5ca4c6e077193b2f2b7420ed57acfa0c0e710", "code_hash": "7bcc2c4d994a9540b65f9dbd426787709c7ad012191e9ee2da20bb3db21faffb", diff --git a/.pdd/meta/pddrc_initializer_python.json b/.pdd/meta/pddrc_initializer_python.json index 2ad36d8cc8..de049a1abd 100644 --- a/.pdd/meta/pddrc_initializer_python.json +++ b/.pdd/meta/pddrc_initializer_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.424685+00:00", + "timestamp": "2026-07-09T19:57:43.079796+00:00", "command": "fix", "prompt_hash": "9399d4347fee000bf46bb4a9414f384bbcd158a8e44f6ba35dc5ef4560c0c6a9", "code_hash": "6112573fcff622386dc139f43d2dc30d99e68a3f362784f059e771648bbb928b", diff --git a/.pdd/meta/pin_example_hack_python.json b/.pdd/meta/pin_example_hack_python.json index 0c8e6ecadd..b09e5a5e92 100644 --- a/.pdd/meta/pin_example_hack_python.json +++ b/.pdd/meta/pin_example_hack_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.426635+00:00", + "timestamp": "2026-07-09T19:57:43.081966+00:00", "command": "fix", "prompt_hash": "677655b3eb5ef57bbe1f4216ce0ceb5abe7ba3ee2f5a94388c2f5bdfcb21383b", "code_hash": "c90df80316bc8339fcf9d4690ac29e4dc8ae3391e25c26c82e496b87dcd4a788", diff --git a/.pdd/meta/postprocess_0_python.json b/.pdd/meta/postprocess_0_python.json index 967824947f..c1b3ea9c62 100644 --- a/.pdd/meta/postprocess_0_python.json +++ b/.pdd/meta/postprocess_0_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.427411+00:00", + "timestamp": "2026-07-09T19:57:43.082782+00:00", "command": "fix", "prompt_hash": "dfb5fe2454d0270eff594b45258a05d3f55d7a0c56f4fafec6d2b6a09556a628", "code_hash": "396d7b1b20852d812b0b25a1dad2f8b32ba1a37ab6c857f6c327a443804b74f3", diff --git a/.pdd/meta/postprocess_python.json b/.pdd/meta/postprocess_python.json index 0bc398b9a1..6cfa913bf8 100644 --- a/.pdd/meta/postprocess_python.json +++ b/.pdd/meta/postprocess_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.428184+00:00", + "timestamp": "2026-07-09T19:57:43.083602+00:00", "command": "fix", "prompt_hash": "3df8ad9a21611349ce5cbb63192882f07d450736a968439868d049fcd6a10817", "code_hash": "628880a68346c3c1bd8326b4d1b495452578937ed97b27234ad56ba332c4c2ed", diff --git a/.pdd/meta/pre_checkup_gate_python.json b/.pdd/meta/pre_checkup_gate_python.json index 14e4449701..0650e75b94 100644 --- a/.pdd/meta/pre_checkup_gate_python.json +++ b/.pdd/meta/pre_checkup_gate_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.430240+00:00", + "timestamp": "2026-07-09T19:57:43.085555+00:00", "command": "fix", "prompt_hash": "7dbedd5a5ab8690a61298f5195269f074161c6218f522bcce599768fdff949ab", "code_hash": "9ff0bbaa18c82cf4da836126861c40936a4555b8ff972f4bceee370492f37ace", diff --git a/.pdd/meta/preprocess_main_python.json b/.pdd/meta/preprocess_main_python.json index 6230508b2f..68737ccd22 100644 --- a/.pdd/meta/preprocess_main_python.json +++ b/.pdd/meta/preprocess_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.432075+00:00", + "timestamp": "2026-07-09T19:57:43.087280+00:00", "command": "fix", - "prompt_hash": "9bdb68754d0f924602000d44462f64207853deb89659c0d9ad1538ad0e128859", + "prompt_hash": "cecb0cae2711dd82a08c6b2041224c4e538e84e90b28f2e8035c877578ad69e6", "code_hash": "a069c3a73be88d3e3e93d40fd66e482c69bfb56ab627d862da31585612ac203b", "example_hash": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "test_hash": "0fa3887c7a4e2c3f051ce719117b8f07444da419b35363b9dff4a2b5ae0f17e9", @@ -11,7 +11,7 @@ "test_preprocess_main_pdd_tags.py": "abddfe41c460aa7dcd4186028134deb4eef0a85419a7f6f59869a274c25f7ee8" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/preprocess_python.json b/.pdd/meta/preprocess_python.json index 9d193b384b..0badd634f2 100644 --- a/.pdd/meta/preprocess_python.json +++ b/.pdd/meta/preprocess_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.433752+00:00", + "timestamp": "2026-07-09T19:57:43.088891+00:00", "command": "fix", "prompt_hash": "029c02ce24a5e0329cd238fc79050d04b8e9eb5ecf030d0c23def59078c941f2", "code_hash": "d04a6cfc261c1e88076398a34d0bf96c4285061668866c5ad305e4b605ffdf56", diff --git a/.pdd/meta/process_csv_change_python.json b/.pdd/meta/process_csv_change_python.json index f951f4cad4..0643abcd96 100644 --- a/.pdd/meta/process_csv_change_python.json +++ b/.pdd/meta/process_csv_change_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.434455+00:00", + "timestamp": "2026-07-09T19:57:43.089681+00:00", "command": "fix", "prompt_hash": "51fda08db3c4bb80bab1047527095d28167707c6e0599c6e349064de59d604f5", "code_hash": "0827d5c0585403e3c5f7c75c2fc07f5e9d5f635faf9159cc4b4182565308cd55", diff --git a/.pdd/meta/prompt_lint_python.json b/.pdd/meta/prompt_lint_python.json index 9457c54fbc..d7e7035be3 100644 --- a/.pdd/meta/prompt_lint_python.json +++ b/.pdd/meta/prompt_lint_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.434976+00:00", + "timestamp": "2026-07-09T19:57:43.090103+00:00", "command": "test", "prompt_hash": "ad547c4d37d4860acab5d4dfac46e9d4caa9182547683f64a5b5ee5caf2b9907", "code_hash": "df85f363082925c714e23be8d7b2e941d62a8542a3370a2581d16780cef1474e", diff --git a/.pdd/meta/prompt_repair_python.json b/.pdd/meta/prompt_repair_python.json index 7af70df1d9..6e74df03f8 100644 --- a/.pdd/meta/prompt_repair_python.json +++ b/.pdd/meta/prompt_repair_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.436108+00:00", + "timestamp": "2026-07-09T19:57:43.091117+00:00", "command": "fix", "prompt_hash": "7534fda4f31eaa0a65b13f01ad13ff704e3976d4a6ce7463320a9b51e293728b", "code_hash": "3bb7949b5d27a078b93f2ec872b9af53b1265dcd2740780b128b527a1cf3346d", diff --git a/.pdd/meta/prompt_tester_python.json b/.pdd/meta/prompt_tester_python.json index 96dd0b296c..568b8534d0 100644 --- a/.pdd/meta/prompt_tester_python.json +++ b/.pdd/meta/prompt_tester_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.436650+00:00", + "timestamp": "2026-07-09T19:57:43.091601+00:00", "command": "fix", "prompt_hash": "db8cacbb67c5c5e4cd986133e3a0b53d93944dae1488f15cf9deb317bcc6a3af", "code_hash": "77fb98a82eee4a2fd8d5f95091c1a1676b270507431503dd35b90c538a279025", diff --git a/.pdd/meta/provider_manager_python.json b/.pdd/meta/provider_manager_python.json index 64fdb9bdf2..057dfee04d 100644 --- a/.pdd/meta/provider_manager_python.json +++ b/.pdd/meta/provider_manager_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.437080+00:00", + "timestamp": "2026-07-09T19:57:43.092112+00:00", "command": "test", "prompt_hash": "47b3f7a1cdecac48fa42942e640be85b68a40908bbb2c4cacab726cedc20c689", "code_hash": "4003ea5149d472ca4c0b04ee456c43619ca3286b89e450aaf28ca1342bef62fc", diff --git a/.pdd/meta/pytest_output_python.json b/.pdd/meta/pytest_output_python.json index 78661c3323..d2768ed99b 100644 --- a/.pdd/meta/pytest_output_python.json +++ b/.pdd/meta/pytest_output_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.437588+00:00", + "timestamp": "2026-07-09T19:57:43.092563+00:00", "command": "fix", "prompt_hash": "2a42925af61c91af5d4c42843b6afe93f68fb8a35b5cee77a8a290f73c269315", "code_hash": "652a27dd1e08769611abe3cb6a83f372c450279d6bf1b676741b9b7186665975", diff --git a/.pdd/meta/pytest_slicer_python.json b/.pdd/meta/pytest_slicer_python.json index e56b727734..deac5c40e3 100644 --- a/.pdd/meta/pytest_slicer_python.json +++ b/.pdd/meta/pytest_slicer_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.438052+00:00", + "timestamp": "2026-07-09T19:57:43.092999+00:00", "command": "fix", "prompt_hash": "2eab3431bb3a44fa472f1f28d490d5841b4c298069b73081f47b4a4336a66fa0", "code_hash": "c02a5488fe6f7248ed387636d5824cb2f1876544d3991e43ef253648a36e49a2", diff --git a/.pdd/meta/python_env_detector_python.json b/.pdd/meta/python_env_detector_python.json index 404e93ac2c..efb9724e49 100644 --- a/.pdd/meta/python_env_detector_python.json +++ b/.pdd/meta/python_env_detector_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.438456+00:00", + "timestamp": "2026-07-09T19:57:43.093401+00:00", "command": "fix", "prompt_hash": "87662b4bec6070ff94de5f45f5fa821b98bd352514b4a5bd1c204961048799ab", "code_hash": "cbe4044a83cd88a683f36d6ecfca245fef6a03ea2abc7f5c407636fccc051f35", diff --git a/.pdd/meta/reasoning_python.json b/.pdd/meta/reasoning_python.json index 43e63e423d..adb2fa124b 100644 --- a/.pdd/meta/reasoning_python.json +++ b/.pdd/meta/reasoning_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.438758+00:00", + "timestamp": "2026-07-09T19:57:43.093658+00:00", "command": "fix", "prompt_hash": "8c85242e5ca00f29a3f6d2dc47702a15a317dd6dfa303609f70e9555cfdf4722", "code_hash": "b75e2beac078d86bcbee0ceb2a44cd19b4fab7a456890eead6510cd2823efa39", diff --git a/.pdd/meta/remote_session_python.json b/.pdd/meta/remote_session_python.json index c2b66fbcce..401f276b59 100644 --- a/.pdd/meta/remote_session_python.json +++ b/.pdd/meta/remote_session_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.439844+00:00", + "timestamp": "2026-07-09T19:57:43.094587+00:00", "command": "fix", "prompt_hash": "9a49cada503bed5d892ea7b68570c6357b6ee220a2f5a41ba1e37204f61e6760", "code_hash": "163292e0200246767f685e9478c8ab4531c06ba471be4ceb9a6ee8065b1cfc12", diff --git a/.pdd/meta/render_mermaid_python.json b/.pdd/meta/render_mermaid_python.json index 4f111997ca..b90294dd2c 100644 --- a/.pdd/meta/render_mermaid_python.json +++ b/.pdd/meta/render_mermaid_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.440204+00:00", + "timestamp": "2026-07-09T19:57:43.095047+00:00", "command": "fix", "prompt_hash": "42ea0f2c0870cd0542cdc8804b0ab3814e6e6e811382f31fbc7f8e692413bf0b", "code_hash": "54ab32f4a65722fd22a49efde8529c413812ee30240b52f68515b94a8032ad57", diff --git a/.pdd/meta/resolved_sync_unit_python.json b/.pdd/meta/resolved_sync_unit_python.json index b1ffe5b9ef..613b5ab952 100644 --- a/.pdd/meta/resolved_sync_unit_python.json +++ b/.pdd/meta/resolved_sync_unit_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.440646+00:00", + "timestamp": "2026-07-09T19:57:43.095566+00:00", "command": "fix", "prompt_hash": "22b41b5041d1747474bb7d1410d0a72393fbd104ac169097e8d8d4f4ea22d9b3", "code_hash": "2ef910bdcf6f4aece8ec9440c554d3775e7ca848ee8e5b8150e4d08960fe347b", diff --git a/.pdd/meta/routing_policy_python.json b/.pdd/meta/routing_policy_python.json index 4eb1f7f551..6e54f77182 100644 --- a/.pdd/meta/routing_policy_python.json +++ b/.pdd/meta/routing_policy_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.441522+00:00", + "timestamp": "2026-07-09T19:57:43.096523+00:00", "command": "fix", "prompt_hash": "98fd165a7e3e936568815cff0b127c2504af6be42780b2e9c56a49bea3fd257d", "code_hash": "3337699ac936552fa0e6d143fc70f6a0183edbbcbc73b1177922f3d8207dab56", diff --git a/.pdd/meta/run_generated_python.json b/.pdd/meta/run_generated_python.json index b18277ec79..bf8edde9e5 100644 --- a/.pdd/meta/run_generated_python.json +++ b/.pdd/meta/run_generated_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.441766+00:00", + "timestamp": "2026-07-09T19:57:43.096853+00:00", "command": "fix", "prompt_hash": "96731fed482942f0acaaf72323a8b588499f8beafab4c6fa739236b1bd941221", "code_hash": "96731fed482942f0acaaf72323a8b588499f8beafab4c6fa739236b1bd941221", diff --git a/.pdd/meta/server_app_python.json b/.pdd/meta/server_app_python.json index 69bc295ba2..1b17e88a01 100644 --- a/.pdd/meta/server_app_python.json +++ b/.pdd/meta/server_app_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.442755+00:00", + "timestamp": "2026-07-09T19:57:43.097809+00:00", "command": "fix", "prompt_hash": "4c5bfabf92ab16c46596507eb86161fc85295e660f90b3120a1e19b95f9e8059", "code_hash": "28394e19c9174f44cda9cf37b93229d74012bd2e61c49e0d03e665796be94279", diff --git a/.pdd/meta/server_click_executor_python.json b/.pdd/meta/server_click_executor_python.json index 9b46b7c23a..bbc671c18b 100644 --- a/.pdd/meta/server_click_executor_python.json +++ b/.pdd/meta/server_click_executor_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.443262+00:00", + "timestamp": "2026-07-09T19:57:43.098268+00:00", "command": "fix", "prompt_hash": "d82aceff435ce2a46ef2f4297f06393f559254168774ef122d905417a8b3ed0d", "code_hash": "b8e1e120d050f0545f2c3979c94390b07431a30af391bfd30bc052770f11edda", diff --git a/.pdd/meta/server_executor_python.json b/.pdd/meta/server_executor_python.json index 8ea1b8852c..2fe63d4c4f 100644 --- a/.pdd/meta/server_executor_python.json +++ b/.pdd/meta/server_executor_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.444087+00:00", + "timestamp": "2026-07-09T19:57:43.099168+00:00", "command": "fix", "prompt_hash": "77f3e901f05b202431961276e304ea0327345a69924dff2caf8ab5322ee9e95f", "code_hash": "7b4662572a02d650c81af625290ecbd7e1823bb3d4247326d726f9ba95fc511c", diff --git a/.pdd/meta/server_jobs_python.json b/.pdd/meta/server_jobs_python.json index d1056314f7..3dab318d72 100644 --- a/.pdd/meta/server_jobs_python.json +++ b/.pdd/meta/server_jobs_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.444909+00:00", + "timestamp": "2026-07-09T19:57:43.099901+00:00", "command": "fix", "prompt_hash": "c79d067d505a37c8d69ffb22ca520baa6ab385be61cd489b9e63627393585dd1", "code_hash": "975aa1aaab1500f7ad8e0dfe667842fb43a5b44e045ebd4e2a7cd177aa0af3e7", diff --git a/.pdd/meta/server_models_python.json b/.pdd/meta/server_models_python.json index 22ee9514b7..f321fc5430 100644 --- a/.pdd/meta/server_models_python.json +++ b/.pdd/meta/server_models_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.445799+00:00", + "timestamp": "2026-07-09T19:57:43.100738+00:00", "command": "fix", "prompt_hash": "afa81609237d8c779745c0e4d660247233d9f7626443976f6efa300e80e6744e", "code_hash": "a17b2f09033b2fe7063f484a2efb59184f7cb2fba822ee25605a93bbe5905941", diff --git a/.pdd/meta/server_routes_architecture_python.json b/.pdd/meta/server_routes_architecture_python.json index 46e5d025fd..75563a41ac 100644 --- a/.pdd/meta/server_routes_architecture_python.json +++ b/.pdd/meta/server_routes_architecture_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.446702+00:00", + "timestamp": "2026-07-09T19:57:43.101639+00:00", "command": "fix", "prompt_hash": "a768e3fc89c1c6f5aa261492547c841a9239893662727f682404d6b749752d37", "code_hash": "67df73835b6282fde848c0ab558f3fa18c108b2b27b20aec8cf23f2f1a291446", diff --git a/.pdd/meta/server_routes_auth_python.json b/.pdd/meta/server_routes_auth_python.json index 3fbbf4bc89..5c8a32889f 100644 --- a/.pdd/meta/server_routes_auth_python.json +++ b/.pdd/meta/server_routes_auth_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.447479+00:00", + "timestamp": "2026-07-09T19:57:43.102526+00:00", "command": "fix", "prompt_hash": "c5ed12c3a857e38d8431cafd7a817c18642693b62bc746681efd7be9c5c0460f", "code_hash": "0964f8ca62a4b95d114f8938c5afd5cf5ec480a350b7bd442fa4fc62ef200eb3", diff --git a/.pdd/meta/server_routes_commands_python.json b/.pdd/meta/server_routes_commands_python.json index 53576def67..2d65eafc2c 100644 --- a/.pdd/meta/server_routes_commands_python.json +++ b/.pdd/meta/server_routes_commands_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.448562+00:00", + "timestamp": "2026-07-09T19:57:43.103703+00:00", "command": "fix", "prompt_hash": "924811be56ddaf51635685a42a7a4019dd92d77486051d5e1e800bcdcf268b08", "code_hash": "aaa1af05971354a74e545756b347fe1f718875bd71d12c4bd51962ad084e0fe4", diff --git a/.pdd/meta/server_routes_config_python.json b/.pdd/meta/server_routes_config_python.json index 2e75505b32..f59efc6fc9 100644 --- a/.pdd/meta/server_routes_config_python.json +++ b/.pdd/meta/server_routes_config_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.449296+00:00", + "timestamp": "2026-07-09T19:57:43.104684+00:00", "command": "fix", "prompt_hash": "7ba89c5ce719f92cc6c9e281f1c94bf2594dd4f0e0229ae9cf75431e2787b11c", "code_hash": "efe80f308a6a2acdb6a207288f746d39f0947da597c44c358595ff7b70e587d9", diff --git a/.pdd/meta/server_routes_extracts_python.json b/.pdd/meta/server_routes_extracts_python.json index 7418cb7219..5673229e20 100644 --- a/.pdd/meta/server_routes_extracts_python.json +++ b/.pdd/meta/server_routes_extracts_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.450292+00:00", + "timestamp": "2026-07-09T19:57:43.105654+00:00", "command": "fix", "prompt_hash": "3ee950acac8a66d9aa2331c30049a7f91935f73b3a9753534e89d98e133a6adc", "code_hash": "1308d4b7c79d5560e31d25c60820405c1e5f3ef2560eb03674f0fb4e9cf03794", diff --git a/.pdd/meta/server_routes_files_python.json b/.pdd/meta/server_routes_files_python.json index 9f02a0104e..9a304a6cda 100644 --- a/.pdd/meta/server_routes_files_python.json +++ b/.pdd/meta/server_routes_files_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.451268+00:00", + "timestamp": "2026-07-09T19:57:43.106612+00:00", "command": "fix", "prompt_hash": "33d6cabb10340b8fae1ab7b0ebe3439b0aff13aacffb9d1f1f837446a92be95c", "code_hash": "966d3704d46b38d3448cad3b9f3b748b61e8b572c4281f6cc063da105e56d290", diff --git a/.pdd/meta/server_routes_prompts_python.json b/.pdd/meta/server_routes_prompts_python.json index e3f058fad0..47a0b41f62 100644 --- a/.pdd/meta/server_routes_prompts_python.json +++ b/.pdd/meta/server_routes_prompts_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.452786+00:00", + "timestamp": "2026-07-09T19:57:43.108085+00:00", "command": "fix", "prompt_hash": "5a129d5e7110839ed03cde6337526e04fd63eec16ab5e6385e999f28ab589f4b", "code_hash": "b49c7a2072243f6d1b3bbe762e1f023d890fbbdccf4c57f882df3de04f7a971f", diff --git a/.pdd/meta/server_routes_websocket_python.json b/.pdd/meta/server_routes_websocket_python.json index b26f3ad1f2..8316ccc5eb 100644 --- a/.pdd/meta/server_routes_websocket_python.json +++ b/.pdd/meta/server_routes_websocket_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.453605+00:00", + "timestamp": "2026-07-09T19:57:43.108827+00:00", "command": "fix", "prompt_hash": "95bf0f052dbb0161c69f356bae8d9cc273dce51db1729e520f87fa48fa40c583", "code_hash": "961fbae5ff5944b4be4104be65320c8bfb3bda62bff4db6eeaf4df8b1da1039a", diff --git a/.pdd/meta/server_security_python.json b/.pdd/meta/server_security_python.json index f97c43c858..ebcfbbdcee 100644 --- a/.pdd/meta/server_security_python.json +++ b/.pdd/meta/server_security_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.454086+00:00", + "timestamp": "2026-07-09T19:57:43.109245+00:00", "command": "fix", "prompt_hash": "e54788c440ea949be62bfd1ce223d9fdb605884254981500234d3d2967e6d2c6", "code_hash": "1eeb395579f49c24ce7a6b695438e74f738af2dac604384bf8e2105c3d6cf4e7", diff --git a/.pdd/meta/server_terminal_spawner_python.json b/.pdd/meta/server_terminal_spawner_python.json index 8c5d83efd6..7a21b0611a 100644 --- a/.pdd/meta/server_terminal_spawner_python.json +++ b/.pdd/meta/server_terminal_spawner_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.454564+00:00", + "timestamp": "2026-07-09T19:57:43.109691+00:00", "command": "fix", "prompt_hash": "c6238db322a2907172a42f470c7a345b8e4703692c1240e522c3e4c8d553a07b", "code_hash": "efffd485569bb2f2e673b408c607a02a9b3325f46d2db8af2f4f8f8439f49fb5", diff --git a/.pdd/meta/server_token_counter_python.json b/.pdd/meta/server_token_counter_python.json index 48b78044e9..0de18e0bff 100644 --- a/.pdd/meta/server_token_counter_python.json +++ b/.pdd/meta/server_token_counter_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.455051+00:00", + "timestamp": "2026-07-09T19:57:43.110139+00:00", "command": "fix", "prompt_hash": "2487fd62e2c8a29e5a404d43df9f63df63eabae82b7e6bbdab9804df9fa8be18", "code_hash": "847ac13e3804c451aca64652877940c06b72c2fc33edc00232f1d4aa16c957e8", diff --git a/.pdd/meta/setup_tool_python.json b/.pdd/meta/setup_tool_python.json index 40cd8220be..80242aad90 100644 --- a/.pdd/meta/setup_tool_python.json +++ b/.pdd/meta/setup_tool_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.456247+00:00", + "timestamp": "2026-07-09T19:57:43.111185+00:00", "command": "fix", "prompt_hash": "ce35b42282c1f64f3c38653035d643e945e8b88a7ee291955b6620fb3e065176", "code_hash": "8d2c78cd67bea21d2637669586eaa49608de0b0d6a5e1d36d6ddb9554e968baa", diff --git a/.pdd/meta/split_main_python.json b/.pdd/meta/split_main_python.json index 06f2e278c5..be5dbc9b2f 100644 --- a/.pdd/meta/split_main_python.json +++ b/.pdd/meta/split_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.457962+00:00", + "timestamp": "2026-07-09T19:57:43.112714+00:00", "command": "fix", - "prompt_hash": "f99f201197b89ba0fac4883806e66b289fd9066a132d282d8e90b79ed65d9717", + "prompt_hash": "54ac70b37397e1803b7d2bc051794c61e7601301d982c350157c5dbc21f42466", "code_hash": "381837b939069c6fef6c115caaefaa34c3103722de6ca95037ced13941edae75", "example_hash": "ced192fcbfbfda15b35bd2dad5bbf4b4888acb091084cf58326832d224a77661", "test_hash": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887", @@ -10,7 +10,7 @@ "test_split_main.py": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/split_python.json b/.pdd/meta/split_python.json index d8ea293882..0ccfe8ed5b 100644 --- a/.pdd/meta/split_python.json +++ b/.pdd/meta/split_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.459639+00:00", + "timestamp": "2026-07-09T19:57:43.114342+00:00", "command": "fix", "prompt_hash": "b3d22d3a857a401b3e28f39864bef2a8bad98b59f0e2046731c878eae8a5b1a1", "code_hash": "45894f5de8eb4f172b375f50858f89476bc39ab25bd1c6f0cf45dbb29f884b1e", diff --git a/.pdd/meta/split_validation_python.json b/.pdd/meta/split_validation_python.json index cbb00b650a..34a9f79d5b 100644 --- a/.pdd/meta/split_validation_python.json +++ b/.pdd/meta/split_validation_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.460460+00:00", + "timestamp": "2026-07-09T19:57:43.115320+00:00", "command": "fix", "prompt_hash": "ac0c920040e138d26877842ef7e159726d5e1ed06d4811ef183449fac331eed5", "code_hash": "e51a9512fc4cedbe362f25da3c97c23a89057901bff10c6b04eeefe77b79dafe", diff --git a/.pdd/meta/story_coverage_python.json b/.pdd/meta/story_coverage_python.json index 679ff073f2..d9703f3e99 100644 --- a/.pdd/meta/story_coverage_python.json +++ b/.pdd/meta/story_coverage_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.460949+00:00", + "timestamp": "2026-07-09T19:57:43.115759+00:00", "command": "fix", "prompt_hash": "372aa16676ec2f4f1e528dbb9c6335b24c4181c8b04123b064704f25cb9b479d", "code_hash": "6d15872bac258806e49feda2cb37ff410d667930905eedec836192395cfd7f75", diff --git a/.pdd/meta/story_regression_gate_python.json b/.pdd/meta/story_regression_gate_python.json index 68b834592f..eba33e3cac 100644 --- a/.pdd/meta/story_regression_gate_python.json +++ b/.pdd/meta/story_regression_gate_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.461439+00:00", + "timestamp": "2026-07-09T19:57:43.116209+00:00", "command": "fix", "prompt_hash": "3c3381a2d75792bdc45e201fe44dc9a1b24cca4a1162c37b1415b043df9a52a9", "code_hash": "51d3dc49dda8a594f71816a83143b1cc14b5c01ac917d17fd9505fc3da2ea06c", diff --git a/.pdd/meta/story_regression_python.json b/.pdd/meta/story_regression_python.json index 4a4374315f..3f0dc55c4f 100644 --- a/.pdd/meta/story_regression_python.json +++ b/.pdd/meta/story_regression_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.462064+00:00", + "timestamp": "2026-07-09T19:57:43.116800+00:00", "command": "fix", "prompt_hash": "689cbfe6e7648a9087f1f20aae4b80260ece0834c8b8673fdda254392d49bed1", "code_hash": "7f3e89234750cf8483659ae2c409ee663d9b2b981b0689b9c9a69c6778a772d5", diff --git a/.pdd/meta/story_test_generator_python.json b/.pdd/meta/story_test_generator_python.json index 60d1fe222a..bc2ba31176 100644 --- a/.pdd/meta/story_test_generator_python.json +++ b/.pdd/meta/story_test_generator_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.462352+00:00", + "timestamp": "2026-07-09T19:57:43.117062+00:00", "command": "fix", "prompt_hash": "08ebc4332fc8aace6e07544ef82bba07e1a1a9eb00ee78086633d510a7c70e35", "code_hash": "8189426246b8bc0c1cc5563b93fbca74cdd5786875f06725c7d0ad78f177a119", diff --git a/.pdd/meta/summarize_directory_python.json b/.pdd/meta/summarize_directory_python.json index e6dabeeee4..64d36c5ae1 100644 --- a/.pdd/meta/summarize_directory_python.json +++ b/.pdd/meta/summarize_directory_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.463319+00:00", + "timestamp": "2026-07-09T19:57:43.117958+00:00", "command": "update", "prompt_hash": "693ec6464aea87ceb2babb81f138ebb328f0bc40eebfc7b8f82344033a81ea84", "code_hash": "e715f8c9f90dd9cb6b656ef83df4a09388edd97451e0706e964fe713eecf6aaf", diff --git a/.pdd/meta/sync_animation_python.json b/.pdd/meta/sync_animation_python.json index 94961f8eef..0267d597eb 100644 --- a/.pdd/meta/sync_animation_python.json +++ b/.pdd/meta/sync_animation_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.464672+00:00", + "timestamp": "2026-07-09T19:57:43.119233+00:00", "command": "fix", - "prompt_hash": "66bd02391a0239cb2977d371ceb48a7ce0bfbd7b5c801db79a88bde530e1dde3", + "prompt_hash": "e22434f9c40895e357448f09b4d0594214ce64040875bdbc8c02de0956e1433c", "code_hash": "b9261a68d14049db76c89179f98ee1c45a073cc9a656607d447612e23f68e285", "example_hash": "5b6a8af940fe44241889a279c1a8d3c978fe0c6ec3afc648510d8e33ffa7b18c", "test_hash": "f76041e4a4e313d3005d5961e76c3b08bfc26549e498d341cefe31560c328ebd", @@ -13,7 +13,7 @@ "test_sync_animation_phases.py": "fa098d0dc0e6bb3f1f45863c1d01cf1a798fdcbaa3a402025aa241a39faef76c" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/logo_animation_example.py": "f32a5cc330235c3b61fb16ac62d3ae7531c7c6dbc11af077fc79054736f0944d", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/sync_determine_operation_python.json b/.pdd/meta/sync_determine_operation_python.json index b23f745b11..04adf4d900 100644 --- a/.pdd/meta/sync_determine_operation_python.json +++ b/.pdd/meta/sync_determine_operation_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.467383+00:00", + "timestamp": "2026-07-09T19:57:43.121416+00:00", "command": "fix", "prompt_hash": "67066038dc835de0304bdf437277088994f8293b858343af8a8c1ba00b7c86a2", "code_hash": "e616ac746674a9f1e8be84bf3093d5e1f45ff0175bc3767b758f2d17b2c54132", diff --git a/.pdd/meta/sync_main_python.json b/.pdd/meta/sync_main_python.json index ca9bad0e8c..e5c70223d1 100644 --- a/.pdd/meta/sync_main_python.json +++ b/.pdd/meta/sync_main_python.json @@ -1,16 +1,16 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.471053+00:00", + "timestamp": "2026-07-09T19:57:43.124070+00:00", "command": "fix", - "prompt_hash": "fcfcfdc0014299ae85bfd643bccd062a5ba57a107ae1f54be6f507303cc85a9b", - "code_hash": "68873b5f5599765e8220419ac18c9f264497f38f0e573308986a0feadda65159", + "prompt_hash": "0d0a2ef9c0bddd8af0017bac0d520cb05905d63177f145b4a052ed1f7af4ac58", + "code_hash": "cca0497f63c1f43f3e8c9359f6a6fa7d0e8b3e9a5082aa911294907b7515b602", "example_hash": "9a7961a4044a54c46ce6c43c8adbbb83da46f233d9c6a9eaa28302440c0052c0", - "test_hash": "9f617d403a3ba62d0f46451bf63d81485f6fb7c4ec0a56a9b342b4c244a8d330", + "test_hash": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1", "test_files": { - "test_sync_main.py": "9f617d403a3ba62d0f46451bf63d81485f6fb7c4ec0a56a9b342b4c244a8d330" + "test_sync_main.py": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1" }, "include_deps": { - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", diff --git a/.pdd/meta/sync_orchestration_python.json b/.pdd/meta/sync_orchestration_python.json index 928efe35bf..2b6ba81a13 100644 --- a/.pdd/meta/sync_orchestration_python.json +++ b/.pdd/meta/sync_orchestration_python.json @@ -1,17 +1,17 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.476722+00:00", + "timestamp": "2026-07-09T19:57:43.127847+00:00", "command": "fix", - "prompt_hash": "31fceea8fcb2e3933a156779918cce48ae3a108541b1a0d5203652cac919a22b", - "code_hash": "66b8002c0123618f6030600e5a68f74eef6c2731ef51e7b9c753f068c55dbe5d", + "prompt_hash": "ddf4cc37489a6c9cbf9aa66986256c4ac357f73ae253f21f3818f429562d9c49", + "code_hash": "be3474324cb8adaa13ff01466a3eb7c7755f6a5b47ca5cc3f52a1ede7dfa6c1b", "example_hash": "cc1313a948946026d418c85a07e5bf0eedeb5915c44d630440e489979755e1f7", - "test_hash": "7a4a23ed7c00408887d4ca9b604cb9715e0ad6e0a9c3e9e1b4df78603b396f41", + "test_hash": "04372c6ac095144c4b58def206e9037fa67e67d7eb5890a363a9e51b8bc7e8e4", "test_files": { - "test_sync_orchestration.py": "7a4a23ed7c00408887d4ca9b604cb9715e0ad6e0a9c3e9e1b4df78603b396f41" + "test_sync_orchestration.py": "04372c6ac095144c4b58def206e9037fa67e67d7eb5890a363a9e51b8bc7e8e4" }, "include_deps": { "docs/whitepaper.md": "3347db03fa35376024b59d8546efdf0858655746490561b88b710fa6b85017cc", - "README.md": "e4cb8873e1b989671efde7b3efbeee8495304682dce9c85c285c3142a8b01d73", + "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", diff --git a/.pdd/meta/sync_order_python.json b/.pdd/meta/sync_order_python.json index 9cf95d75c9..7fd40b8849 100644 --- a/.pdd/meta/sync_order_python.json +++ b/.pdd/meta/sync_order_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.478137+00:00", + "timestamp": "2026-07-09T19:57:43.129047+00:00", "command": "fix", "prompt_hash": "427b20071b0f873b8a9db5550f040fbea6ba89a49ae58f421ceccfc545679616", "code_hash": "6cdaed3b56d9cc12f38ee5ac93b8623899372ea2d177c4f131ec258edb94d0dd", diff --git a/.pdd/meta/sync_tui_python.json b/.pdd/meta/sync_tui_python.json index 2ec24f87ea..2203215f80 100644 --- a/.pdd/meta/sync_tui_python.json +++ b/.pdd/meta/sync_tui_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.478680+00:00", + "timestamp": "2026-07-09T19:57:43.129525+00:00", "command": "update", "prompt_hash": "5eb3bb0151fa49a4f51f87c06051545bfa07a3bdf27718f23616a6a301deefa2", "code_hash": "941cbbd6026742784188c66b97d64479daa733ffe1ff2d3d11f464e8a0e10992", diff --git a/.pdd/meta/template_expander_python.json b/.pdd/meta/template_expander_python.json index 890843b9c6..1b12f3f2b9 100644 --- a/.pdd/meta/template_expander_python.json +++ b/.pdd/meta/template_expander_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.479083+00:00", + "timestamp": "2026-07-09T19:57:43.129906+00:00", "command": "fix", "prompt_hash": "a4c8ce5c8c337cf066e40130e120241bb16ae0c40ef874618269301f602c4d6c", "code_hash": "bcaa670f334b9fa7726aa85906e70125ad2cd4b7e7b62a8e39f8bdd06c975edb", diff --git a/.pdd/meta/template_registry_python.json b/.pdd/meta/template_registry_python.json index c00f5378cb..7617890782 100644 --- a/.pdd/meta/template_registry_python.json +++ b/.pdd/meta/template_registry_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.479489+00:00", + "timestamp": "2026-07-09T19:57:43.130308+00:00", "command": "fix", "prompt_hash": "28ec666c9c2ed6e91cf715d33bf544910ac0ccc825e10bca2fc3d514f65ea6b3", "code_hash": "3b1b6758f82296d4d6aacef5bdd9a8fd597107ddd3cda8b8aa021102958308f2", diff --git a/.pdd/meta/test_context_packer_python.json b/.pdd/meta/test_context_packer_python.json index 641f1d7345..0d9d994ba6 100644 --- a/.pdd/meta/test_context_packer_python.json +++ b/.pdd/meta/test_context_packer_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.480073+00:00", + "timestamp": "2026-07-09T19:57:43.131050+00:00", "command": "fix", "prompt_hash": "e64578e078de825466c5b754a15fa32b4c50bdda7f7d34879d92d3c2efa1d6c7", "code_hash": "27c7d14747d38df8edf24c8ef2ce1b7ca21d8f2eea38aec02ba06042ee144c0b", diff --git a/.pdd/meta/trace_main_python.json b/.pdd/meta/trace_main_python.json index 6b11576515..d675f7755c 100644 --- a/.pdd/meta/trace_main_python.json +++ b/.pdd/meta/trace_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.480909+00:00", + "timestamp": "2026-07-09T19:57:43.132067+00:00", "command": "fix", "prompt_hash": "2e2223ee3b5d3af757758c871e32a57e8ede5c485cbd8db0f89a3ed04b73c874", "code_hash": "48e9cc107b5af5668c031ba532b93a685a2399ae2d8bad482ef269dcd561a5b8", diff --git a/.pdd/meta/trace_python.json b/.pdd/meta/trace_python.json index dd3f9d37cd..1d9597ab8b 100644 --- a/.pdd/meta/trace_python.json +++ b/.pdd/meta/trace_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.482548+00:00", + "timestamp": "2026-07-09T19:57:43.133472+00:00", "command": "fix", "prompt_hash": "42c3207f2f44e00b5ae055219f4a518548fd3c129c037be591edc92f8ff9673f", "code_hash": "9ff879812f1def2c14995b939a3b6541590ee68a7f62b25e57064ac7d642fbcb", diff --git a/.pdd/meta/track_cost_python.json b/.pdd/meta/track_cost_python.json index 669c46ccf6..d73d57a9f6 100644 --- a/.pdd/meta/track_cost_python.json +++ b/.pdd/meta/track_cost_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.483135+00:00", + "timestamp": "2026-07-09T19:57:43.133852+00:00", "command": "update", "prompt_hash": "caff809a3e28802d4aa83f89a1b9b4c183e484713d91f8324444093817c272ad", "code_hash": "b8776071f0f9c97a4fd10d6f9bf55faab99dde3757d47e836ef51d1c41b8513c", diff --git a/.pdd/meta/unfinished_prompt_python.json b/.pdd/meta/unfinished_prompt_python.json index 9b92e78b68..ff2861aa6b 100644 --- a/.pdd/meta/unfinished_prompt_python.json +++ b/.pdd/meta/unfinished_prompt_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.483932+00:00", + "timestamp": "2026-07-09T19:57:43.134554+00:00", "command": "fix", "prompt_hash": "5f54934748a49136dbd656ec52e97590e7fd493d4299dbf01f111a3a4b78ed3c", "code_hash": "b012d1c6fab0579ae674d2d6e26be119dd9288c7ba2741b75af516be7a4564bf", diff --git a/.pdd/meta/update_main_python.json b/.pdd/meta/update_main_python.json index a833e79ff4..9eec0b75f0 100644 --- a/.pdd/meta/update_main_python.json +++ b/.pdd/meta/update_main_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.486715+00:00", + "timestamp": "2026-07-09T19:57:43.137328+00:00", "command": "fix", "prompt_hash": "eb13aca686c206ea223dc9b6093627de4f37b158303323caa579311d65ac06e7", "code_hash": "968fb4ec74af3245c758d975888e418c0ec2251edc14d56d545648538ccc10a6", diff --git a/.pdd/meta/update_model_costs_python.json b/.pdd/meta/update_model_costs_python.json index a9f49bc62e..cdad8eef3c 100644 --- a/.pdd/meta/update_model_costs_python.json +++ b/.pdd/meta/update_model_costs_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.487298+00:00", + "timestamp": "2026-07-09T19:57:43.138426+00:00", "command": "fix", "prompt_hash": "b21d140be33ba15fa136934ddb6862522cad498a6d33c9d4ffc9d7777dfa5755", "code_hash": "ca390bd220734fbd7f4588b1a060628dfa9f298335af827f616902ff60a7f38d", diff --git a/.pdd/meta/update_prompt_python.json b/.pdd/meta/update_prompt_python.json index adf7b24b65..0c6b22ab61 100644 --- a/.pdd/meta/update_prompt_python.json +++ b/.pdd/meta/update_prompt_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.489099+00:00", + "timestamp": "2026-07-09T19:57:43.140350+00:00", "command": "fix", "prompt_hash": "1c92d709faafdcb2346184c538c57eff6afbbcf25e974f10d59f5eaaabf52916", "code_hash": "4237e3fb40f2c1bb8f60f2d22305b80365f54c7834c1e97d997fcf803d52417e", diff --git a/.pdd/meta/user_story_tests_python.json b/.pdd/meta/user_story_tests_python.json index 7a631b2060..bf3963f45c 100644 --- a/.pdd/meta/user_story_tests_python.json +++ b/.pdd/meta/user_story_tests_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.489840+00:00", + "timestamp": "2026-07-09T19:57:43.141062+00:00", "command": "fix", "prompt_hash": "18dd7b5a64063a5a942be847810537e6a22b436046bb698f1e891e3ebc2d5463", "code_hash": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc", diff --git a/.pdd/meta/validate_prompt_includes_python.json b/.pdd/meta/validate_prompt_includes_python.json index 877928170c..87f00d064c 100644 --- a/.pdd/meta/validate_prompt_includes_python.json +++ b/.pdd/meta/validate_prompt_includes_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.490718+00:00", + "timestamp": "2026-07-09T19:57:43.141803+00:00", "command": "fix", "prompt_hash": "8a1052a5a135f25c7a0106f13a19977606a55fdfb4b06124f708c4db8ede6f54", "code_hash": "fa97b72a58534e255768634f928f4cfdd2130a7a4d8b296da3eefdf77d47855b", diff --git a/.pdd/meta/xml_tagger_python.json b/.pdd/meta/xml_tagger_python.json index 38fe13e9e1..791e2263ac 100644 --- a/.pdd/meta/xml_tagger_python.json +++ b/.pdd/meta/xml_tagger_python.json @@ -1,6 +1,6 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.491578+00:00", + "timestamp": "2026-07-09T19:57:43.142504+00:00", "command": "fix", "prompt_hash": "9d86a05cae62bf793be21f5b99d1bd77a82299b1b85146da2cac32c74ca978dd", "code_hash": "9cb3c692f9bf5c5eb54d758887a26268aafe51f327f0996e6476121f452ffbec", From c145bc00b40ab1867e92ecc01245c420d7c85cb3 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:14:14 -0700 Subject: [PATCH 13/30] Make both-changed CONFLICT message actionable; demote dead LLM path (#1929) The prompt+derived co-edit branch already returns a non-destructive fail_and_request_manual_merge / CONFLICT decision (landed in #1954). This makes its reason self-actionable: it names the unit, states which artifacts moved, and gives the exact 'pdd resolve --accept-current / --prompt-wins / --code-wins' commands. details now carries basename, language, changed_files, and a resolution_commands map for machine consumers. analyze_conflict_with_llm is documented as reserved (not wired into the decision path) so it is no longer a parallel auto-resolver. Prompt prose realigned: removes the stale unlink/delete/recurse description of the old destructive branch and describes the actionable CONFLICT contract. Co-Authored-By: Claude --- .pdd/meta/metadata_sync_python.json | 6 +- .pdd/meta/pre_checkup_gate_python.json | 6 +- .../meta/sync_determine_operation_python.json | 6 +- .../sync_determine_operation_python.prompt | 8 +-- pdd/sync_determine_operation.py | 69 +++++++++++++++++-- 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/.pdd/meta/metadata_sync_python.json b/.pdd/meta/metadata_sync_python.json index 5ed74e2508..d32b93acf2 100644 --- a/.pdd/meta/metadata_sync_python.json +++ b/.pdd/meta/metadata_sync_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.420359+00:00", + "timestamp": "2026-07-09T20:13:33.515482+00:00", "command": "fix", - "prompt_hash": "8ccd27574100139772388c34fcab32fbae253154d449f1ffeead270d6c92dc8d", + "prompt_hash": "ec39af8e67928925ff79e523ad4abb47bff291fe7996b13f23b91bf7a6aa879a", "code_hash": "3afaa5a409e500b3f91aab33dacee33fae47447fba80a1702d65a33761261782", "example_hash": "704453b3386724eef225b61c48f2fe922e1a973ac211c494e1d955dd44bcca11", "test_hash": "82af9e0bff7550d1f9bf46f4c6e7f4792143565e4e228d1507976f6b9fbac5f6", @@ -14,6 +14,6 @@ "pdd/architecture_registry.py": "5722225846b9cc8189b410a78e5714b4f2916d5748271d27f6f738692429c309", "pdd/architecture_sync.py": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", - "pdd/sync_determine_operation.py": "e616ac746674a9f1e8be84bf3093d5e1f45ff0175bc3767b758f2d17b2c54132" + "pdd/sync_determine_operation.py": "764fc1f22c682fd6bb146731060a20f33a2c1caf921079abcda385a7be443a81" } } \ No newline at end of file diff --git a/.pdd/meta/pre_checkup_gate_python.json b/.pdd/meta/pre_checkup_gate_python.json index 14e4449701..c5590085d2 100644 --- a/.pdd/meta/pre_checkup_gate_python.json +++ b/.pdd/meta/pre_checkup_gate_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.430240+00:00", + "timestamp": "2026-07-09T20:13:33.528956+00:00", "command": "fix", - "prompt_hash": "7dbedd5a5ab8690a61298f5195269f074161c6218f522bcce599768fdff949ab", + "prompt_hash": "c3b8587745897302c814327cecd1f09db60d92dee4b3506a42a6d42b93f95308", "code_hash": "9ff0bbaa18c82cf4da836126861c40936a4555b8ff972f4bceee370492f37ace", "example_hash": "82585fac9350c3436528870c0b1d7e64228e6903cc4b5d0a62a35edecb266906", "test_hash": "d22520612cce8bf31712ff999b5f5f45153ddcd63a4044eb82c220d4a8021f62", @@ -16,6 +16,6 @@ "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "pdd/checkup_gates.py": "b6086954a93e0495661e6ca39d96b3079b928d13308bf0fcd6a16b1e0b5f511c", "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", - "pdd/sync_determine_operation.py": "e616ac746674a9f1e8be84bf3093d5e1f45ff0175bc3767b758f2d17b2c54132" + "pdd/sync_determine_operation.py": "764fc1f22c682fd6bb146731060a20f33a2c1caf921079abcda385a7be443a81" } } \ No newline at end of file diff --git a/.pdd/meta/sync_determine_operation_python.json b/.pdd/meta/sync_determine_operation_python.json index b23f745b11..3871862378 100644 --- a/.pdd/meta/sync_determine_operation_python.json +++ b/.pdd/meta/sync_determine_operation_python.json @@ -1,9 +1,9 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.467383+00:00", + "timestamp": "2026-07-09T20:13:33.585502+00:00", "command": "fix", - "prompt_hash": "67066038dc835de0304bdf437277088994f8293b858343af8a8c1ba00b7c86a2", - "code_hash": "e616ac746674a9f1e8be84bf3093d5e1f45ff0175bc3767b758f2d17b2c54132", + "prompt_hash": "d09025959647edcc9076cb860723b3c563ab08415a021656dc2274421c576759", + "code_hash": "764fc1f22c682fd6bb146731060a20f33a2c1caf921079abcda385a7be443a81", "example_hash": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5", "test_hash": "0e896d21fdf4a2974a3fc0ae3332308e2f2d3d30f4fdb13d39b075c3fb8ec04d", "test_files": { diff --git a/pdd/prompts/sync_determine_operation_python.prompt b/pdd/prompts/sync_determine_operation_python.prompt index 4e4d10de72..585fc26dae 100644 --- a/pdd/prompts/sync_determine_operation_python.prompt +++ b/pdd/prompts/sync_determine_operation_python.prompt @@ -21,7 +21,7 @@ You are an expert Python developer. Your task is to implement the core decision- ### Requirements: -1. **Authoritative Fingerprints**: Compare current file SHA256 hashes against `.pdd/meta/{safe_basename}_{lang}.json`. Sanitize basenames containing `/` (e.g., `core/cloud` → `core_cloud`) for metadata filenames. When using sanitized basenames in glob patterns (e.g., in `_check_example_success_history`), apply `glob.escape()` so that special characters like `[`, `]`, `(`, `)` in basenames are treated as literals, not glob metacharacters. `get_meta_dir(project_root=None, paths=None)` resolves the meta directory in this order (issue #1211): explicit `project_root` → upward `.pddrc` from any file in `paths` (handles subproject .pddrc BELOW run CWD) → nearest `.pddrc` walking up from CWD → run CWD. `read_fingerprint(basename, language, paths=None)` and `read_run_report(basename, language, paths=None)` accept the same `paths` hint and forward it. `_perform_sync_analysis` resolves `_initial_paths = get_pdd_file_paths(...)` once at the top and threads them into the early `read_fingerprint` / `read_run_report` reads plus `_check_example_success_history`; `_is_workflow_complete` threads its own `paths` argument into every read it makes. The prompt-and-derived-files-both-changed conflict branch resolves the deletion target via `get_meta_dir(paths=paths)` — NOT a bare `get_meta_dir()` — so the unlink happens in the same `.pdd/meta` the reads came from. Without that, the read sees a subproject fingerprint while the delete targets the parent CWD orphan, and the recursive `_perform_sync_analysis` call re-enters with the same stale state (infinite loop / repeated decisions). This ensures sync decisions read from, and reset against, the subproject's `.pdd/meta` rather than an orphan one under a parent CWD. +1. **Authoritative Fingerprints**: Compare current file SHA256 hashes against `.pdd/meta/{safe_basename}_{lang}.json`. Sanitize basenames containing `/` (e.g., `core/cloud` → `core_cloud`) for metadata filenames. When using sanitized basenames in glob patterns (e.g., in `_check_example_success_history`), apply `glob.escape()` so that special characters like `[`, `]`, `(`, `)` in basenames are treated as literals, not glob metacharacters. `get_meta_dir(project_root=None, paths=None)` resolves the meta directory in this order (issue #1211): explicit `project_root` → upward `.pddrc` from any file in `paths` (handles subproject .pddrc BELOW run CWD) → nearest `.pddrc` walking up from CWD → run CWD. `read_fingerprint(basename, language, paths=None)` and `read_run_report(basename, language, paths=None)` accept the same `paths` hint and forward it. `_perform_sync_analysis` resolves `_initial_paths = get_pdd_file_paths(...)` once at the top and threads them into the early `read_fingerprint` / `read_run_report` reads plus `_check_example_success_history`; `_is_workflow_complete` threads its own `paths` argument into every read it makes. The prompt-and-derived-files-both-changed CONFLICT branch resolves its metadata paths via `get_meta_dir(paths=paths)` — NOT a bare `get_meta_dir()` — so the preserved fingerprint/run-report paths reported in the decision `details['metadata_preserved']` come from the same `.pdd/meta` the reads came from (a subproject `.pdd/meta` below the run CWD, not a parent-CWD orphan). The branch is non-destructive: it never deletes metadata and never recurses into a fresh no-fingerprint analysis (#1929) — it returns a terminal `fail_and_request_manual_merge` decision, so there is no stale-state re-entry (previously an infinite-loop / repeated-decision hazard). This ensures sync decisions read from the subproject's `.pdd/meta` rather than an orphan one under a parent CWD. 2. **Robust Locking**: `SyncLock` context manager using `fcntl`/`msvcrt` file-descriptor locking. Handle re-entrancy (same PID), stale locks (`psutil.pid_exists`), and cleanup on failure. `log_mode=True` bypasses locking entirely and implies read-only analysis. 3. **Deterministic Decision Priority** (strict ordering): 1. Auto-deps completion → always `generate` after `auto-deps` (prevents infinite loop). @@ -34,7 +34,7 @@ You are an expert Python developer. Your task is to implement the core decision- 4. Coverage gaps → `test_extend` (Python only) or `all_synced` (non-Python, since coverage tooling is Python-specific). When `PDD_DISABLE_TEST_EXTEND` is truthy (`1`, `true`, `yes`, or `on`, case-insensitive), Python coverage gaps MUST also return the existing `all_synced` no-op shape with `test_extend_skipped: True` and a skip reason citing the disabled `test_extend` guard instead of returning `test_extend`. This suppression affects only coverage-driven `test_extend`; all other operation priorities remain unchanged. 5. Missing derived files → code → example → test (respecting `skip_tests`/`skip_verify` flags). 6. Isolated replay/repair override → when `isolated_replay_or_repair=True`, missing or stale examples must not preempt code replay/repair decisions. Existing examples may be read as context, but the decision engine must not schedule `example` unless the caller explicitly requested example regeneration. - 7. Conflict: prompt + derived files both changed → return `fail_and_request_manual_merge` with an explicit conflict reason and details that identify the changed artifacts. Preserve the existing fingerprint and run-report in both mutable and read-only/log analysis; do not delete metadata, re-run fresh analysis, or choose either the prompt or derived artifact as the winner. Derived-only changes → `verify` or `test` (not a conflict). + 7. Conflict: prompt + derived files both changed → return `fail_and_request_manual_merge` with `details['classification'] == 'CONFLICT'`. The `reason` must be actionable on its own — it names the unit, states which artifacts moved, and gives the exact resolution commands (`pdd resolve --accept-current` / `--prompt-wins` / `--code-wins`, with a `--language` suffix for non-Python units) — and `details` carries `basename`, `language`, `changed_files`, and a `resolution_commands` map. Preserve the existing fingerprint and run-report in both mutable and read-only/log analysis; do not delete metadata, re-run fresh analysis, or choose either the prompt or derived artifact as the winner. Derived-only changes → `verify` or `test` (not a conflict). 4. **Skip Flags**: `skip_tests` and `skip_verify` parameters flow through `sync_determine_operation`, `_is_workflow_complete`, and `_handle_missing_expected_files`. When `skip_tests=True`, low coverage returns `all_synced` instead of `test`/`test_extend`. When both `skip_tests=True` and `skip_verify=True`, workflow completion requires only the prompt/code/example file set and must not require run reports, test reports, or verification fingerprints. Stale or failing cached test-results from `run_report` must be ignored (do not recommend `fix` or `crash`) when `skip_tests` is active. 5. **Context Override**: All path-resolving functions accept `context_override` to select a specific `.pddrc` context. `_relative_basename_for_context` strips context-specific prefixes from basenames for template expansion. For prompts_dir values, extract the prefix after the 'prompts/' segment wherever it appears in the path (e.g., 'prompts/frontend' → 'frontend', 'extensions/app/prompts/frontend' → 'frontend'). Use `_extract_prefix_from_prompts_dir()` from `construct_paths` for this. 6. **Path Resolution (Issue #237, #1169, #1303)**: Use `construct_paths` for configuration-aware pathing. If `.pddrc` has an `outputs` template section, use `_generate_paths_from_templates`. `_resolve_prompts_root` resolves prompts_dir relative to `.pddrc` location. Case-insensitive prompt file lookups must return the actual on-disk filename casing even when a lowercased candidate path reports `exists()` on case-insensitive filesystems. When the constructed prompt path does not exist, `_find_prompt_file` searches recursively through `prompts_root` subdirectories for a case-insensitive filename match (both basename and language suffix are case-insensitive). When multiple nested files share the basename, `context_override` scopes to the correct `.pddrc` context subdirectory, then basename directory hints disambiguate, then ties are broken by shallowest path-part count then lexicographic order. This ensures prompts in nested directories (e.g., `prompts/src/clients/firestore_client_Python.prompt`) are found even when `get_pdd_file_paths` is called with a flat basename and lowercase language. `_resolve_prompt_path_from_architecture` also performs a recursive case-insensitive search when its naively-joined path does not exist on disk. When architecture.json supplies a `filepath`, use the basename-resolved `.pddrc` context for example/test directories rather than cwd/default context, so repos with context-specific examples (e.g., `context/`, `context/commands/`) do not drift to `examples/`. When the prompt file does not exist yet (new module creation), `.pddrc` context's `prompts_dir` prefix is applied to the fallback path. @@ -83,7 +83,7 @@ You are an expert Python developer. Your task is to implement the core decision- 5. **Decision Logic (`sync_determine_operation`)**: Accepts `basename, language, target_coverage, budget, log_mode, prompts_dir, skip_tests, skip_verify, context_override, read_only`, plus an optional isolated replay/repair indicator consumed by sync orchestration. Delegates to `_perform_sync_analysis` (with or without lock). Follow the priority order in Requirement 3. 6. **Isolated replay/repair mode:** Preserve the default missing-file priority for ordinary full sync. When the caller marks the analysis as an isolated generation replay or code repair, missing or stale example files must not preempt `generate`, `verify`, or `fix` unless the requested operation explicitly requires example regeneration. Include a decision reason explaining that example generation was skipped for isolated replay/repair so dry-run output and operation logs are auditable. 7. **Workflow Completion (`_is_workflow_complete`)**: Requires all files exist, run_report with success, coverage > 0 when tests pass, non-stale test hashes, and fingerprint command in `{verify, test, fix, update}` (not prefixed with `skip:`). If both `skip_tests` and `skip_verify` are true, return complete after required code/example existence checks because the caller explicitly requested metadata-only sync analysis. -8. **LLM Conflict Resolution**: `analyze_conflict_with_llm` gathers git diffs (with brace-escaping for `.format()`), formats `sync_analysis_LLM` template, calls `llm_invoke` with `temperature=0`. Falls back to `fail_and_request_manual_merge` on any error or confidence < 0.75. +8. **LLM Conflict Resolution (reserved, not in the decision path)**: `analyze_conflict_with_llm` gathers git diffs (with brace-escaping for `.format()`), formats `sync_analysis_LLM` template, calls `llm_invoke` with `temperature=0`, and falls back to `fail_and_request_manual_merge` on any error or confidence < 0.75. Per #1929 this helper is NOT wired into `sync_determine_operation`: the deterministic decision tree never auto-picks a winner for the both-changed case (it returns the explicit CONFLICT decision above). The function is retained only as the LLM backend reserved for a future `pdd resolve`-driven agentic 3-way merge. ### Deliverables: @@ -93,5 +93,5 @@ A standalone Python module `sync_determine_operation.py` containing: - `get_pdd_file_paths`, `_generate_paths_from_templates`, and hashing utilities. - `sync_determine_operation` (primary entry point) and `_perform_sync_analysis`. - `_check_example_success_history`, `validate_expected_files`, `_handle_missing_expected_files`. -- `analyze_conflict_with_llm` (LLM fallback). +- `analyze_conflict_with_llm` (reserved LLM backend for `pdd resolve`; not wired into the decision path — #1929). - `estimate_operation_cost`, `check_for_dependencies`. diff --git a/pdd/sync_determine_operation.py b/pdd/sync_determine_operation.py index 99e0e35a24..0ed51f2567 100644 --- a/pdd/sync_determine_operation.py +++ b/pdd/sync_determine_operation.py @@ -2013,6 +2013,35 @@ def _changed_artifacts_from_hashes( return changes +def _conflict_command_suffix(language: str) -> str: + """CLI suffix that disambiguates non-Python units in resolution commands.""" + return "" if language.lower() == "python" else f" --language {language}" + + +def _describe_conflict_artifacts(changes: List[str]) -> str: + """Human phrase for the co-edited artifacts, prompt first ('prompt and code').""" + order = ("prompt", "code", "example", "test") + ordered = [item for item in order if item in changes] + ordered += [item for item in changes if item not in ordered] + if not ordered: + return "prompt and derived artifacts" + if len(ordered) == 1: + return ordered[0] + if len(ordered) == 2: + return f"{ordered[0]} and {ordered[1]}" + return ", ".join(ordered[:-1]) + f", and {ordered[-1]}" + + +def _conflict_resolution_commands(basename: str, language: str) -> Dict[str, str]: + """Exact `pdd resolve` commands offered for a CONFLICT unit.""" + suffix = _conflict_command_suffix(language) + return { + "accept_current": f"pdd resolve {basename}{suffix} --accept-current", + "prompt_wins": f"pdd resolve {basename}{suffix} --prompt-wins", + "code_wins": f"pdd resolve {basename}{suffix} --code-wins", + } + + def _prompt_derived_conflict_decision( *, basename: str, @@ -2022,21 +2051,45 @@ def _prompt_derived_conflict_decision( fingerprint: Optional[Fingerprint], read_only: bool, ) -> SyncDecision: - """Return the explicit conflict decision for prompt+derived co-edits.""" + """Return the explicit, non-destructive CONFLICT decision for prompt+derived co-edits. + + The prompt AND one or more derived artifacts both changed since the last + synced fingerprint. pdd must not auto-pick a winner here (regenerating would + discard the manual code edits; `pdd update` would discard the prompt edits), + so this returns the terminal ``fail_and_request_manual_merge`` operation with + an explicit ``CONFLICT`` classification. The fingerprint and run report are + preserved (never deleted) as the record of the last-synced ancestor so that + ``pdd resolve`` can finalize an informed choice. The ``reason`` is written to + be actionable on its own: it names the unit, what moved, and the exact + resolution commands. + """ meta_dir = get_meta_dir(paths=paths) safe_bn = _safe_basename(basename) fp_path = meta_dir / f"{safe_bn}_{language.lower()}.json" rr_path = meta_dir / f"{safe_bn}_{language.lower()}_run.json" + resolution_commands = _conflict_resolution_commands(basename, language) + moved = _describe_conflict_artifacts(changes) + reason = ( + f"CONFLICT: '{basename}' — {moved} changed since the last sync, so pdd " + f"will not auto-pick a winner (that would discard your edits). Resolve with " + f"`{resolution_commands['accept_current']}` (keep the current files as the new " + f"baseline), `{resolution_commands['prompt_wins']}` (regenerate code from the " + f"prompt), or `{resolution_commands['code_wins']}` (back-propagate the code " + f"into the prompt)." + ) return SyncDecision( operation='fail_and_request_manual_merge', - reason='Prompt and derived artifacts changed since the last fingerprint; manual conflict resolution required', + reason=reason, confidence=1.0, estimated_cost=estimate_operation_cost('fail_and_request_manual_merge'), details={ 'decision_type': 'heuristic', 'classification': 'CONFLICT', + 'basename': basename, + 'language': language, 'changed_files': changes, 'read_only': read_only, + 'resolution_commands': resolution_commands, 'metadata_preserved': [ str(path) for path in (fp_path, rr_path) if path.exists() ], @@ -3323,14 +3376,22 @@ def analyze_conflict_with_llm( ) -> SyncDecision: """ Resolve complex sync conflicts using an LLM. - + + NOTE (#1929): this helper is NOT part of the deterministic decision path. + The both-changed (prompt+derived) case is classified explicitly as CONFLICT + by ``_prompt_derived_conflict_decision`` and surfaced to the user via + ``pdd resolve`` — the decision tree never auto-picks a winner. This function + is retained only as the LLM backend reserved for a future + ``pdd resolve``-driven agentic 3-way merge; it must not be wired back into + ``sync_determine_operation`` as an automatic conflict resolver. + Args: basename: The base name for the PDD unit language: The programming language fingerprint: The last known good state changed_files: List of files that have changed prompts_dir: Directory containing prompt files - + Returns: SyncDecision object with LLM-recommended operation """ From cb368667d3e1dce5112ad7a454278e9e69456bf4 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:16:50 -0700 Subject: [PATCH 14/30] Add `pdd resolve` command for CONFLICT units (#1929) pdd resolve --accept-current deterministically stamps the current working tree as the agreed baseline (re-fingerprint via continuous_sync's save_fingerprint core), turning a CONFLICT unit IN_SYNC without any LLM call. Command-level transactional: re-classifies after stamping and only reports success when the unit lands IN_SYNC (exit 0), else non-zero. --prompt-wins / --code-wins are documented previews of the LLM strategies (regenerate from prompt / back-propagate to prompt): they print what WOULD run and exit non-zero ('not yet automated'). Exactly one strategy is required. Modeled on commands/reconcile.py (commands/ dir, no prompt) so it is exempt from the architecture-completeness and fingerprint-stamper gates, both of which stay green. Co-Authored-By: Claude --- pdd/commands/__init__.py | 2 + pdd/commands/resolve.py | 209 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 pdd/commands/resolve.py diff --git a/pdd/commands/__init__.py b/pdd/commands/__init__.py index 21e8725eb1..187b2cda2f 100644 --- a/pdd/commands/__init__.py +++ b/pdd/commands/__init__.py @@ -24,6 +24,7 @@ from .firecrawl import firecrawl_cache from .story import story_cli from .reconcile import install_hooks, reconcile +from .resolve import resolve def register_commands(cli: click.Group) -> None: """Register all subcommands with the main CLI group.""" @@ -55,6 +56,7 @@ def register_commands(cli: click.Group) -> None: cli.add_command(which) cli.add_command(reconcile) cli.add_command(install_hooks) + cli.add_command(resolve) # Register templates group directly to commands dict to handle nesting if needed, # or just add_command works for groups too. diff --git a/pdd/commands/resolve.py b/pdd/commands/resolve.py new file mode 100644 index 0000000000..ea2db8a5cb --- /dev/null +++ b/pdd/commands/resolve.py @@ -0,0 +1,209 @@ +"""`pdd resolve` — resolve a both-changed CONFLICT unit. + +A CONFLICT arises when a unit's prompt AND one or more derived artifacts (code, +example, test) both changed since the last synced fingerprint. `pdd sync` refuses +to auto-pick a winner there (see ``sync_determine_operation`` #1929); this command +lets the user finalize the resolution explicitly: + +* ``--accept-current`` — deterministic, no LLM. Stamp the current working tree as + the agreed baseline for the unit (re-fingerprint), so the co-edited prompt and + code are recorded as the new last-synced ancestor. Use this after hand-merging. +* ``--prompt-wins`` / ``--code-wins`` — documented previews of the LLM-backed + strategies (regenerate code from the prompt / back-propagate code into the + prompt). These are not yet automated; they print what WOULD run and exit + non-zero. +""" +from __future__ import annotations + +import json +from typing import Dict, Optional + +import click + +from ..continuous_sync import SyncUnit, classify_unit, discover_units, project_root +from ..operation_log import save_fingerprint +from ..sync_determine_operation import get_pdd_file_paths, read_fingerprint + +# Fingerprint commands treated as "settled" workflow states. Preserving one of +# these (rather than resetting to a running op) keeps a stamped baseline from +# re-triggering verify/test on the next sync — mirrors continuous_sync._heal_units. +_SETTLED_COMMANDS = {"verify", "test", "fix", "update"} + + +def _find_unit(basename: str, language: str) -> Optional[SyncUnit]: + """Locate the discovered sync unit for ``basename``/``language`` (or None).""" + base = project_root() + for unit in discover_units(base, modules=[basename]): + if unit.language == language and unit.basename == basename: + return unit + # Fall back to a language-only match (basename may be path-qualified/aliased). + for unit in discover_units(base, modules=[basename]): + if unit.language == language: + return unit + return None + + +def _baseline_command(basename: str, language: str, paths: Dict) -> str: + """Command to record on the accepted baseline fingerprint.""" + fingerprint = read_fingerprint(basename, language, paths=paths) + if fingerprint and fingerprint.command in _SETTLED_COMMANDS: + return fingerprint.command + return "fix" + + +def _accept_current(unit: SyncUnit, as_json: bool, quiet: bool) -> int: + """Stamp the current tree as the agreed baseline for ``unit``. + + Transactional at the command level: it re-fingerprints, then re-classifies + and only reports success when the unit lands IN_SYNC. Any other post-state is + surfaced as a failure rather than a silent partial stamp. + """ + base = project_root() + before = classify_unit(unit, base) + paths = get_pdd_file_paths( + unit.basename, unit.language, prompts_dir=str(unit.prompts_dir) + ) + command = _baseline_command(unit.basename, unit.language, paths) + save_fingerprint(unit.basename, unit.language, command, paths, 0.0, "resolve") + after = classify_unit(unit, base) + + resolved = after["classification"] == "IN_SYNC" + result = { + "basename": unit.basename, + "language": unit.language, + "strategy": "accept-current", + "before": before["classification"], + "after": after["classification"], + "changed_files": before.get("changed_files", []), + "fingerprint_path": after.get("fingerprint_path"), + "resolved": resolved, + } + if as_json: + click.echo(json.dumps(result, indent=2, sort_keys=True)) + elif not quiet: + if resolved: + moved = ", ".join(before.get("changed_files", [])) or "no tracked" + click.echo( + f"Resolved '{unit.basename}' ({unit.language}) with --accept-current: " + f"stamped the current tree as the new baseline " + f"(was {before['classification']}: {moved} changed)." + ) + else: + click.echo( + f"Could not fully resolve '{unit.basename}' ({unit.language}): " + f"after stamping it is {after['classification']}, not IN_SYNC. " + f"Ensure the prompt and its derived artifacts all exist on disk, " + f"then retry." + ) + return 0 if resolved else 1 + + +def _preview_llm_strategy(basename: str, language: str, strategy: str) -> int: + """Print what a not-yet-automated LLM strategy WOULD run; return non-zero.""" + suffix = "" if language.lower() == "python" else f" --language {language}" + if strategy == "prompt-wins": + would_run = f"pdd sync {basename}{suffix}" + effect = "regenerate the code from the prompt (an LLM generation)" + else: # code-wins + would_run = f"pdd update {basename}{suffix}" + effect = "back-propagate the code into the prompt (an LLM update)" + click.echo( + f"--{strategy} would run `{would_run}` to {effect}, then re-stamp the " + f"fingerprint. This LLM-backed strategy is not yet automated by " + f"`pdd resolve`." + ) + click.echo( + "Run that command yourself, or use " + f"`pdd resolve {basename}{suffix} --accept-current` to keep the current " + "tree as the baseline." + ) + return 2 + + +@click.command("resolve") +@click.argument("basename") +@click.option( + "--language", + default="python", + show_default=True, + help="Language of the unit to resolve.", +) +@click.option( + "--accept-current", + "accept_current", + is_flag=True, + default=False, + help="Stamp the current tree as the agreed baseline (deterministic, no LLM).", +) +@click.option( + "--prompt-wins", + "prompt_wins", + is_flag=True, + default=False, + help="[preview] Regenerate code from the prompt (not yet automated).", +) +@click.option( + "--code-wins", + "code_wins", + is_flag=True, + default=False, + help="[preview] Back-propagate code into the prompt (not yet automated).", +) +@click.option( + "--json", + "as_json", + is_flag=True, + default=False, + help="Emit machine-readable JSON.", +) +@click.pass_context +def resolve( + ctx: click.Context, + basename: str, + language: str, + accept_current: bool, + prompt_wins: bool, + code_wins: bool, + as_json: bool, +) -> None: + # pylint: disable=too-many-arguments,too-many-positional-arguments + """Resolve a CONFLICT unit (prompt and code both changed since last sync). + + Choose exactly one strategy: --accept-current keeps the current files as the + new baseline; --prompt-wins / --code-wins preview the LLM strategies. + """ + ctx.ensure_object(dict) + if as_json: + ctx.obj["_suppress_result_summary"] = True + quiet = ctx.obj.get("quiet", False) + + chosen = [ + name + for name, flag in ( + ("--accept-current", accept_current), + ("--prompt-wins", prompt_wins), + ("--code-wins", code_wins), + ) + if flag + ] + if len(chosen) != 1: + raise click.UsageError( + "Choose exactly one of --accept-current, --prompt-wins, --code-wins." + ) + + if prompt_wins: + raise click.exceptions.Exit( + _preview_llm_strategy(basename, language, "prompt-wins") + ) + if code_wins: + raise click.exceptions.Exit( + _preview_llm_strategy(basename, language, "code-wins") + ) + + unit = _find_unit(basename, language) + if unit is None: + raise click.ClickException( + f"No PDD unit '{basename}' ({language}) found to resolve. " + f"Run `pdd sync` or `pdd reconcile` to see tracked units." + ) + raise click.exceptions.Exit(_accept_current(unit, as_json, quiet)) From a0241283c6a3fc71a4810aac7f675d9057116cc3 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:18:41 -0700 Subject: [PATCH 15/30] Add ranked code-ahead prompt-catchup work queue (A2) Enumerate every python unit (reusing stamp_fingerprints unit resolution) and rank the code-ahead ones -- code committed more recently than its prompt -- by drift churn: added+deleted lines on the code file since 2026-04-01 over commits that touched code but NOT the prompt. 75 of 229 units are code-ahead. 43 are conflict_risk: the prompt's most recent (non-merge, in-window) commit touched the prompt but NOT the code, i.e. a standalone prompt edit never reconciled with code by a joint commit -- pdd update (code->prompt) there could clobber deliberate prompt intent, so these are flagged for human review and must NOT be auto-updated. The remaining 32 are pure staleness (prompt last synced WITH code by a joint commit, then code drifted): safe to back-propagate. conflict_risk uses the pathspec-free per-commit file map from the window log; a per-unit 'git log -- ' cannot be used because the pathspec filters --name-only down to just the prompt, hiding whether the same commit also touched code. scripts/build_prompt_catchup_queue.py regenerates scripts/prompt_catchup_queue.json. Co-Authored-By: Claude --- scripts/build_prompt_catchup_queue.py | 324 ++++++ scripts/prompt_catchup_queue.json | 1439 +++++++++++++++++++++++++ 2 files changed, 1763 insertions(+) create mode 100644 scripts/build_prompt_catchup_queue.py create mode 100644 scripts/prompt_catchup_queue.json diff --git a/scripts/build_prompt_catchup_queue.py b/scripts/build_prompt_catchup_queue.py new file mode 100644 index 0000000000..978cebee46 --- /dev/null +++ b/scripts/build_prompt_catchup_queue.py @@ -0,0 +1,324 @@ +#!/usr/bin/env python3 +"""Build the ranked *code-ahead* work queue for the prompt catch-up pass (issue A2). + +A "code-ahead" unit is one whose module code (``pdd/.py``) has a more recent +commit than its prompt (``pdd/prompts/_python.prompt``): code landed without a +corresponding prompt update, so "regenerate from prompt" would resurrect stale +behavior (doctrine anti-pattern "Prompt Drift"). This script enumerates every +python unit (reusing ``stamp_fingerprints.enumerate_units`` so code/prompt paths +resolve exactly as the fingerprint oracle sees them), then for each computes: + +* ``code_last`` / ``prompt_last``: most recent commit author-date (ALL history) of + the code file and the prompt file. A unit is code-ahead when + ``code_last > prompt_last``. +* ``days_ahead``: how many days the code leads the prompt. +* churn since ``--since`` (default 2026-04-01), split by what each commit touched: + - ``churn_lines`` / ``churn_commits``: added+deleted lines / commit count over + commits that touched the **code but not the prompt** (the drift-producing + commits). This is the ranking weight. + - ``prompt_only_commits`` / ``both_commits``: commits touching only the prompt / + both — surfaced so a reviewer can spot units whose prompt was ALSO edited + independently (``conflict_risk``: ``pdd update`` there could clobber a + deliberate prompt change; do not auto-update). +* ``code_loc``: current line count of the code file (pilot-size filter). + +Ranked by (churn_lines, days_ahead, churn_commits) descending. Output JSON is the +committed work-queue artifact (``scripts/prompt_catchup_queue.json``). Stdlib only, +no ``pdd`` import, no LLM. +""" +from __future__ import annotations + +import argparse +import json +import subprocess +import sys +from datetime import datetime +from pathlib import Path +from typing import Dict, List, Optional, Tuple + +SCRIPTS_DIR = Path(__file__).resolve().parent +REPO_ROOT = SCRIPTS_DIR.parent +sys.path.insert(0, str(SCRIPTS_DIR)) + +import stamp_fingerprints as sf # noqa: E402 (stdlib-only, no side effects) + +DEFAULT_SINCE = "2026-04-01" + + +def _git(args: List[str]) -> str: + """Run a read-only git command in the repo, returning stdout.""" + out = subprocess.run( + ["git", "-C", str(REPO_ROOT), *args], + capture_output=True, + text=True, + check=False, + ) + return out.stdout or "" + + +def _rel(path: Path) -> str: + """Repo-relative POSIX path for a file under the repo root.""" + return path.resolve().relative_to(REPO_ROOT).as_posix() + + +def _normalize_numstat_path(field: str) -> str: + """Normalize a --numstat path field, resolving git rename syntax to the new path. + + Handles both ``old => new`` and ``dir/{old => new}/leaf`` forms so churn lands + on the current path. Binary files show ``-`` counts and are handled by callers. + """ + field = field.strip() + if "=>" not in field: + return field + if "{" in field and "}" in field: + pre = field[: field.index("{")] + inner = field[field.index("{") + 1 : field.index("}")] + post = field[field.index("}") + 1 :] + new = inner.split("=>")[-1].strip() + return (pre + new + post).replace("//", "/") + return field.split("=>")[-1].strip() + + +def load_window_commits(since: str) -> Tuple[Dict[str, List[dict]], Dict[str, set]]: + """Parse one ``git log --numstat`` pass over the window. + + Returns ``(by_file, commit_files)`` where ``by_file[path]`` is a list of + ``{sha, date, added, deleted}`` for every commit in ``[since, now]`` that + touched ``path``, and ``commit_files[sha]`` is the set of paths that commit + touched. Author date (``%aI``) is used throughout. + """ + raw = _git( + [ + "log", + f"--since={since}T00:00:00", + "--no-merges", + "--numstat", + "--date=iso-strict", + "--format=@@C@@%H|%aI", + ] + ) + by_file: Dict[str, List[dict]] = {} + commit_files: Dict[str, set] = {} + sha = "" + date = "" + for line in raw.splitlines(): + if line.startswith("@@C@@"): + sha, date = line[len("@@C@@") :].split("|", 1) + commit_files.setdefault(sha, set()) + continue + if not line.strip() or not sha: + continue + parts = line.split("\t") + if len(parts) != 3: + continue + added_s, deleted_s, path_field = parts + path = _normalize_numstat_path(path_field) + added = 0 if added_s == "-" else int(added_s) + deleted = 0 if deleted_s == "-" else int(deleted_s) + by_file.setdefault(path, []).append( + {"sha": sha, "date": date, "added": added, "deleted": deleted} + ) + commit_files[sha].add(path) + return by_file, commit_files + + +def load_last_commit_dates(targets: set) -> Dict[str, str]: + """Most-recent commit author-date (ALL history) for each path in ``targets``. + + One reverse-chronological ``git log --name-only`` pass; the first time a path + appears is its most recent commit. Stops early once every target is found. + """ + raw = _git(["log", "--name-status", "--date=iso-strict", "--format=@@C@@%aI"]) + last: Dict[str, str] = {} + remaining = set(targets) + date = "" + for line in raw.splitlines(): + if line.startswith("@@C@@"): + date = line[len("@@C@@") :].strip() + continue + if not line.strip() or not remaining: + continue + # name-status rows: "M\tpath" or "R100\told\tnew"; take the last field. + parts = line.split("\t") + path = _normalize_numstat_path(parts[-1]) + if path in remaining: + last[path] = date + remaining.discard(path) + if not remaining: + break + return last + + +def _iso_date(s: Optional[str]) -> Optional[datetime]: + if not s: + return None + try: + return datetime.fromisoformat(s) + except ValueError: + return None + + +def prompt_last_is_standalone( + prompt_commits: List[dict], code_rel: str, commit_files: Dict[str, set] +) -> bool: + """True when the prompt's most recent (non-merge, in-window) commit did NOT touch code. + + For a code-ahead unit this is the precise conflict signal: the current prompt + state came from a standalone prompt edit never reconciled with code via a joint + commit, so ``pdd update`` (code -> prompt) could clobber deliberate prompt + intent. If the prompt's last commit also touched the code (a proper joint sync) + the divergence is pure staleness and safe to back-propagate. + + Uses the pathspec-free ``commit_files`` map (full file set per commit) built by + ``load_window_commits`` -- a per-unit ``git log -- `` cannot be used + because the pathspec filters ``--name-only`` down to just the prompt, hiding the + code file. Returns False when the prompt has no in-window commits (pure + staleness: the prompt has not been touched since the window start). + """ + if not prompt_commits: + return False + latest = max(prompt_commits, key=lambda c: c["date"]) + return code_rel not in commit_files.get(latest["sha"], set()) + + +def _code_loc(path: Path) -> Optional[int]: + try: + return sum(1 for _ in path.open("r", encoding="utf-8", errors="ignore")) + except OSError: + return None + + +def build_queue(since: str) -> dict: + units = sf.enumerate_units() + by_file, commit_files = load_window_commits(since) + + targets: set = set() + resolved: List[Tuple[sf.Unit, str, str]] = [] + for unit in units: + if not unit.prompt.exists() or not unit.code.exists(): + continue + code_rel = _rel(unit.code) + prompt_rel = _rel(unit.prompt) + targets.add(code_rel) + targets.add(prompt_rel) + resolved.append((unit, code_rel, prompt_rel)) + + last_dates = load_last_commit_dates(targets) + + rows: List[dict] = [] + for unit, code_rel, prompt_rel in resolved: + code_last = last_dates.get(code_rel) + prompt_last = last_dates.get(prompt_rel) + cd = _iso_date(code_last) + pd = _iso_date(prompt_last) + code_ahead = bool(cd and (pd is None or cd > pd)) + days_ahead = round((cd - pd).total_seconds() / 86400.0, 2) if (cd and pd) else None + + code_commits = by_file.get(code_rel, []) + churn_lines = 0 + churn_commits = 0 + both_commits = 0 + last_code_only_date: Optional[str] = None + for c in code_commits: + touched_prompt = prompt_rel in commit_files.get(c["sha"], set()) + if touched_prompt: + both_commits += 1 + else: + churn_commits += 1 + churn_lines += c["added"] + c["deleted"] + if last_code_only_date is None or c["date"] > last_code_only_date: + last_code_only_date = c["date"] + + prompt_commits = by_file.get(prompt_rel, []) + prompt_only_commits = sum( + 1 for c in prompt_commits if code_rel not in commit_files.get(c["sha"], set()) + ) + last_prompt_only_date: Optional[str] = None + for c in prompt_commits: + if code_rel not in commit_files.get(c["sha"], set()): + if last_prompt_only_date is None or c["date"] > last_prompt_only_date: + last_prompt_only_date = c["date"] + + # Conflict risk: the prompt's most recent commit was a standalone prompt + # edit (touched prompt, not code) never reconciled with code by a joint + # commit -- a deliberate prompt change `pdd update` could overwrite. + # Reviewer must inspect before running update; flagged, never auto-updated. + # Only computed for code-ahead units (the update candidates). + conflict_risk = code_ahead and prompt_last_is_standalone( + prompt_commits, code_rel, commit_files + ) + + rows.append( + { + "basename": unit.basename, + "code": code_rel, + "prompt": prompt_rel, + "meta": _rel(unit.meta) if unit.meta.exists() else None, + "code_last": code_last, + "prompt_last": prompt_last, + "code_ahead": code_ahead, + "days_ahead": days_ahead, + "churn_lines": churn_lines, + "churn_commits": churn_commits, + "both_commits": both_commits, + "prompt_only_commits": prompt_only_commits, + "last_code_only_date": last_code_only_date, + "last_prompt_only_date": last_prompt_only_date, + "conflict_risk": conflict_risk, + "code_loc": _code_loc(unit.code), + } + ) + + ahead = [r for r in rows if r["code_ahead"]] + ahead.sort( + key=lambda r: (r["churn_lines"], r["days_ahead"] or 0, r["churn_commits"]), + reverse=True, + ) + for i, r in enumerate(ahead, 1): + r["rank"] = i + + total_units = len(rows) + ahead_with_churn = [r for r in ahead if r["churn_lines"] > 0] + return { + "generated_at": datetime.now().astimezone().isoformat(), + "since": since, + "generator": "scripts/build_prompt_catchup_queue.py", + "definition": ( + "code_ahead = code_last commit newer than prompt_last commit (all " + "history). churn_lines = added+deleted on the code file over commits " + "since `since` that touched code but NOT the prompt (drift commits). " + "Ranked by (churn_lines, days_ahead, churn_commits) desc." + ), + "stats": { + "total_python_units": total_units, + "code_ahead_units": len(ahead), + "code_ahead_with_window_churn": len(ahead_with_churn), + "conflict_risk_units": sum(1 for r in ahead if r["conflict_risk"]), + }, + "queue": ahead, + } + + +def main(argv: Optional[List[str]] = None) -> int: + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument("--since", default=DEFAULT_SINCE, help="Churn window start (YYYY-MM-DD).") + parser.add_argument( + "--output", + default=str(SCRIPTS_DIR / "prompt_catchup_queue.json"), + help="Output JSON path.", + ) + args = parser.parse_args(argv) + data = build_queue(args.since) + Path(args.output).write_text(json.dumps(data, indent=2) + "\n", encoding="utf-8") + s = data["stats"] + print( + f"wrote {args.output}: {s['code_ahead_units']} code-ahead / " + f"{s['total_python_units']} units " + f"({s['code_ahead_with_window_churn']} with window churn, " + f"{s['conflict_risk_units']} conflict-risk)" + ) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/prompt_catchup_queue.json b/scripts/prompt_catchup_queue.json new file mode 100644 index 0000000000..ee8fe8eb84 --- /dev/null +++ b/scripts/prompt_catchup_queue.json @@ -0,0 +1,1439 @@ +{ + "generated_at": "2026-07-09T13:18:28.864683-07:00", + "since": "2026-04-01", + "generator": "scripts/build_prompt_catchup_queue.py", + "definition": "code_ahead = code_last commit newer than prompt_last commit (all history). churn_lines = added+deleted on the code file over commits since `since` that touched code but NOT the prompt (drift commits). Ranked by (churn_lines, days_ahead, churn_commits) desc.", + "stats": { + "total_python_units": 229, + "code_ahead_units": 75, + "code_ahead_with_window_churn": 75, + "conflict_risk_units": 43 + }, + "queue": [ + { + "basename": "checkup_agent", + "code": "pdd/checkup_agent.py", + "prompt": "pdd/prompts/checkup_agent_python.prompt", + "meta": ".pdd/meta/checkup_agent_python.json", + "code_last": "2026-06-10T18:09:20-07:00", + "prompt_last": "2026-06-10T11:01:51-07:00", + "code_ahead": true, + "days_ahead": 0.3, + "churn_lines": 1844, + "churn_commits": 15, + "both_commits": 2, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-10T18:09:20-07:00", + "last_prompt_only_date": "2026-06-10T11:01:51-07:00", + "conflict_risk": true, + "code_loc": 1081, + "rank": 1 + }, + { + "basename": "cli_detector", + "code": "pdd/cli_detector.py", + "prompt": "pdd/prompts/cli_detector_python.prompt", + "meta": ".pdd/meta/cli_detector_python.json", + "code_last": "2026-06-16T12:31:10-07:00", + "prompt_last": "2026-06-15T21:46:51Z", + "code_ahead": true, + "days_ahead": 0.91, + "churn_lines": 1486, + "churn_commits": 3, + "both_commits": 8, + "prompt_only_commits": 4, + "last_code_only_date": "2026-06-16T12:31:10-07:00", + "last_prompt_only_date": "2026-06-15T21:46:51Z", + "conflict_risk": true, + "code_loc": 1002, + "rank": 2 + }, + { + "basename": "commands/checkup_simplify", + "code": "pdd/checkup_simplify.py", + "prompt": "pdd/prompts/commands/checkup_simplify_python.prompt", + "meta": ".pdd/meta/commands_checkup_simplify_python.json", + "code_last": "2026-06-10T11:24:07-07:00", + "prompt_last": "2026-05-27T14:31:23-07:00", + "code_ahead": true, + "days_ahead": 13.87, + "churn_lines": 1165, + "churn_commits": 8, + "both_commits": 1, + "prompt_only_commits": 0, + "last_code_only_date": "2026-06-10T11:24:07-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 962, + "rank": 3 + }, + { + "basename": "contract_check", + "code": "pdd/contract_check.py", + "prompt": "pdd/prompts/contract_check_python.prompt", + "meta": ".pdd/meta/contract_check_python.json", + "code_last": "2026-06-01T20:53:52-07:00", + "prompt_last": "2026-05-27T12:05:21-07:00", + "code_ahead": true, + "days_ahead": 5.37, + "churn_lines": 1054, + "churn_commits": 5, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-01T20:53:52-07:00", + "last_prompt_only_date": "2026-05-27T12:05:21-07:00", + "conflict_risk": true, + "code_loc": 946, + "rank": 4 + }, + { + "basename": "evidence_manifest", + "code": "pdd/evidence_manifest.py", + "prompt": "pdd/prompts/evidence_manifest_python.prompt", + "meta": ".pdd/meta/evidence_manifest_python.json", + "code_last": "2026-06-03T14:01:48-07:00", + "prompt_last": "2026-06-03T02:01:41Z", + "code_ahead": true, + "days_ahead": 0.79, + "churn_lines": 1044, + "churn_commits": 16, + "both_commits": 6, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-03T14:01:48-07:00", + "last_prompt_only_date": "2026-06-03T01:10:09Z", + "conflict_risk": false, + "code_loc": 801, + "rank": 5 + }, + { + "basename": "update_main", + "code": "pdd/update_main.py", + "prompt": "pdd/prompts/update_main_python.prompt", + "meta": ".pdd/meta/update_main_python.json", + "code_last": "2026-06-23T17:41:58-07:00", + "prompt_last": "2026-06-18T21:24:14-07:00", + "code_ahead": true, + "days_ahead": 4.85, + "churn_lines": 1033, + "churn_commits": 19, + "both_commits": 7, + "prompt_only_commits": 7, + "last_code_only_date": "2026-06-23T17:41:58-07:00", + "last_prompt_only_date": "2026-06-18T21:24:14-07:00", + "conflict_risk": true, + "code_loc": 2045, + "rank": 6 + }, + { + "basename": "split_validation", + "code": "pdd/split_validation.py", + "prompt": "pdd/prompts/split_validation_python.prompt", + "meta": ".pdd/meta/split_validation_python.json", + "code_last": "2026-06-04T17:57:48-07:00", + "prompt_last": "2026-05-07T19:16:44-07:00", + "code_ahead": true, + "days_ahead": 27.95, + "churn_lines": 1016, + "churn_commits": 2, + "both_commits": 2, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-04T17:57:48-07:00", + "last_prompt_only_date": "2026-05-06T21:30:35-07:00", + "conflict_risk": false, + "code_loc": 1116, + "rank": 7 + }, + { + "basename": "core/cli", + "code": "pdd/core/cli.py", + "prompt": "pdd/prompts/core/cli_python.prompt", + "meta": ".pdd/meta/core_cli_python.json", + "code_last": "2026-07-08T18:16:00-07:00", + "prompt_last": "2026-07-08T13:42:51-07:00", + "code_ahead": true, + "days_ahead": 0.19, + "churn_lines": 921, + "churn_commits": 38, + "both_commits": 6, + "prompt_only_commits": 5, + "last_code_only_date": "2026-07-08T18:16:00-07:00", + "last_prompt_only_date": "2026-07-03T09:56:47-07:00", + "conflict_risk": false, + "code_loc": 1123, + "rank": 8 + }, + { + "basename": "architecture_sync", + "code": "pdd/architecture_sync.py", + "prompt": "pdd/prompts/architecture_sync_python.prompt", + "meta": ".pdd/meta/architecture_sync_python.json", + "code_last": "2026-06-09T15:58:34-07:00", + "prompt_last": "2026-06-03T21:29:45-07:00", + "code_ahead": true, + "days_ahead": 5.77, + "churn_lines": 910, + "churn_commits": 9, + "both_commits": 6, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-09T15:58:34-07:00", + "last_prompt_only_date": "2026-05-18T13:50:20-07:00", + "conflict_risk": false, + "code_loc": 2033, + "rank": 9 + }, + { + "basename": "checkup_prompt_main", + "code": "pdd/checkup_prompt_main.py", + "prompt": "pdd/prompts/checkup_prompt_main_python.prompt", + "meta": ".pdd/meta/checkup_prompt_main_python.json", + "code_last": "2026-06-10T14:45:41-07:00", + "prompt_last": "2026-06-09T19:04:40Z", + "code_ahead": true, + "days_ahead": 1.11, + "churn_lines": 855, + "churn_commits": 12, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-10T14:45:41-07:00", + "last_prompt_only_date": "2026-06-09T19:04:40Z", + "conflict_risk": true, + "code_loc": 685, + "rank": 10 + }, + { + "basename": "prompt_repair", + "code": "pdd/prompt_repair.py", + "prompt": "pdd/prompts/prompt_repair_python.prompt", + "meta": ".pdd/meta/prompt_repair_python.json", + "code_last": "2026-06-10T14:45:41-07:00", + "prompt_last": "2026-06-06T11:03:30-07:00", + "code_ahead": true, + "days_ahead": 4.15, + "churn_lines": 836, + "churn_commits": 8, + "both_commits": 2, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-10T14:45:41-07:00", + "last_prompt_only_date": "2026-06-06T10:42:18-07:00", + "conflict_risk": false, + "code_loc": 713, + "rank": 11 + }, + { + "basename": "coverage_contracts", + "code": "pdd/coverage_contracts.py", + "prompt": "pdd/prompts/coverage_contracts_python.prompt", + "meta": ".pdd/meta/coverage_contracts_python.json", + "code_last": "2026-07-02T12:01:45-07:00", + "prompt_last": "2026-06-22T23:13:25Z", + "code_ahead": true, + "days_ahead": 9.83, + "churn_lines": 788, + "churn_commits": 9, + "both_commits": 1, + "prompt_only_commits": 3, + "last_code_only_date": "2026-07-02T12:01:45-07:00", + "last_prompt_only_date": "2026-06-29T21:27:31Z", + "conflict_risk": true, + "code_loc": 994, + "rank": 12 + }, + { + "basename": "commands/maintenance", + "code": "pdd/commands/maintenance.py", + "prompt": "pdd/prompts/commands/maintenance_python.prompt", + "meta": ".pdd/meta/commands_maintenance_python.json", + "code_last": "2026-07-09T04:59:18-07:00", + "prompt_last": "2026-07-08T18:16:00-07:00", + "code_ahead": true, + "days_ahead": 0.45, + "churn_lines": 771, + "churn_commits": 21, + "both_commits": 9, + "prompt_only_commits": 7, + "last_code_only_date": "2026-07-09T04:59:18-07:00", + "last_prompt_only_date": "2026-06-02T20:43:19Z", + "conflict_risk": false, + "code_loc": 1013, + "rank": 13 + }, + { + "basename": "checkup_report", + "code": "pdd/checkup_report.py", + "prompt": "pdd/prompts/checkup_report_python.prompt", + "meta": ".pdd/meta/checkup_report_python.json", + "code_last": "2026-06-10T16:25:17-07:00", + "prompt_last": "2026-06-10T00:36:59-07:00", + "code_ahead": true, + "days_ahead": 0.66, + "churn_lines": 710, + "churn_commits": 10, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-10T16:25:17-07:00", + "last_prompt_only_date": "2026-06-10T00:36:59-07:00", + "conflict_risk": true, + "code_loc": 527, + "rank": 14 + }, + { + "basename": "preprocess", + "code": "pdd/preprocess.py", + "prompt": "pdd/prompts/preprocess_python.prompt", + "meta": ".pdd/meta/preprocess_python.json", + "code_last": "2026-06-23T14:31:23-07:00", + "prompt_last": "2026-06-23T13:58:59-07:00", + "code_ahead": true, + "days_ahead": 0.02, + "churn_lines": 682, + "churn_commits": 26, + "both_commits": 9, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-23T14:31:23-07:00", + "last_prompt_only_date": "2026-06-08T17:30:50-07:00", + "conflict_risk": false, + "code_loc": 1488, + "rank": 15 + }, + { + "basename": "codex_subscription", + "code": "pdd/codex_subscription.py", + "prompt": "pdd/prompts/codex_subscription_python.prompt", + "meta": ".pdd/meta/codex_subscription_python.json", + "code_last": "2026-05-30T19:12:21-07:00", + "prompt_last": "2026-05-29T16:53:21-07:00", + "code_ahead": true, + "days_ahead": 1.1, + "churn_lines": 657, + "churn_commits": 5, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-05-30T19:12:21-07:00", + "last_prompt_only_date": "2026-05-29T16:53:21-07:00", + "conflict_risk": true, + "code_loc": 459, + "rank": 16 + }, + { + "basename": "user_story_tests", + "code": "pdd/user_story_tests.py", + "prompt": "pdd/prompts/user_story_tests_python.prompt", + "meta": ".pdd/meta/user_story_tests_python.json", + "code_last": "2026-07-06T15:30:33-07:00", + "prompt_last": "2026-07-02T19:22:29Z", + "code_ahead": true, + "days_ahead": 4.13, + "churn_lines": 636, + "churn_commits": 13, + "both_commits": 5, + "prompt_only_commits": 7, + "last_code_only_date": "2026-07-06T15:30:33-07:00", + "last_prompt_only_date": "2026-07-02T19:22:29Z", + "conflict_risk": true, + "code_loc": 1738, + "rank": 17 + }, + { + "basename": "gate", + "code": "pdd/gate_main.py", + "prompt": "pdd/prompts/gate_python.prompt", + "meta": null, + "code_last": "2026-06-06T09:32:54-07:00", + "prompt_last": "2026-05-28T14:38:50-07:00", + "code_ahead": true, + "days_ahead": 8.79, + "churn_lines": 626, + "churn_commits": 7, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-06T09:32:54-07:00", + "last_prompt_only_date": "2026-05-28T14:38:50-07:00", + "conflict_risk": true, + "code_loc": 462, + "rank": 18 + }, + { + "basename": "checkup_interactive_main", + "code": "pdd/checkup_interactive_main.py", + "prompt": "pdd/prompts/checkup_interactive_main_python.prompt", + "meta": ".pdd/meta/checkup_interactive_main_python.json", + "code_last": "2026-06-10T16:12:44-07:00", + "prompt_last": "2026-06-10T00:36:59-07:00", + "code_ahead": true, + "days_ahead": 0.65, + "churn_lines": 592, + "churn_commits": 6, + "both_commits": 2, + "prompt_only_commits": 0, + "last_code_only_date": "2026-06-10T16:12:44-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 548, + "rank": 19 + }, + { + "basename": "track_cost", + "code": "pdd/track_cost.py", + "prompt": "pdd/prompts/track_cost_python.prompt", + "meta": ".pdd/meta/track_cost_python.json", + "code_last": "2026-06-16T12:20:03-07:00", + "prompt_last": "2026-06-15T22:56:19Z", + "code_ahead": true, + "days_ahead": 0.85, + "churn_lines": 555, + "churn_commits": 6, + "both_commits": 3, + "prompt_only_commits": 9, + "last_code_only_date": "2026-06-16T12:20:03-07:00", + "last_prompt_only_date": "2026-06-15T22:56:19Z", + "conflict_risk": true, + "code_loc": 241, + "rank": 20 + }, + { + "basename": "sync_main", + "code": "pdd/sync_main.py", + "prompt": "pdd/prompts/sync_main_python.prompt", + "meta": ".pdd/meta/sync_main_python.json", + "code_last": "2026-06-23T17:41:58-07:00", + "prompt_last": "2026-06-23T14:25:48-07:00", + "code_ahead": true, + "days_ahead": 0.14, + "churn_lines": 551, + "churn_commits": 20, + "both_commits": 9, + "prompt_only_commits": 5, + "last_code_only_date": "2026-06-23T17:41:58-07:00", + "last_prompt_only_date": "2026-06-23T14:25:48-07:00", + "conflict_risk": true, + "code_loc": 1413, + "rank": 21 + }, + { + "basename": "commands/modify", + "code": "pdd/commands/modify.py", + "prompt": "pdd/prompts/commands/modify_python.prompt", + "meta": ".pdd/meta/commands_modify_python.json", + "code_last": "2026-07-09T04:59:18-07:00", + "prompt_last": "2026-06-12T15:51:13-07:00", + "code_ahead": true, + "days_ahead": 26.55, + "churn_lines": 409, + "churn_commits": 16, + "both_commits": 11, + "prompt_only_commits": 3, + "last_code_only_date": "2026-07-09T04:59:18-07:00", + "last_prompt_only_date": "2026-06-10T11:24:07-07:00", + "conflict_risk": false, + "code_loc": 639, + "rank": 22 + }, + { + "basename": "routing_policy", + "code": "pdd/routing_policy.py", + "prompt": "pdd/prompts/routing_policy_python.prompt", + "meta": ".pdd/meta/routing_policy_python.json", + "code_last": "2026-06-16T13:19:28-07:00", + "prompt_last": "2026-06-15T22:31:12Z", + "code_ahead": true, + "days_ahead": 0.91, + "churn_lines": 384, + "churn_commits": 1, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-16T13:19:28-07:00", + "last_prompt_only_date": "2026-06-15T22:31:12Z", + "conflict_risk": true, + "code_loc": 384, + "rank": 23 + }, + { + "basename": "commands/gate", + "code": "pdd/commands/gate.py", + "prompt": "pdd/prompts/commands/gate_python.prompt", + "meta": ".pdd/meta/commands_gate_python.json", + "code_last": "2026-06-05T16:09:59-07:00", + "prompt_last": "2026-05-28T14:38:50-07:00", + "code_ahead": true, + "days_ahead": 8.06, + "churn_lines": 378, + "churn_commits": 3, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-05T16:09:59-07:00", + "last_prompt_only_date": "2026-05-28T14:38:50-07:00", + "conflict_risk": true, + "code_loc": 308, + "rank": 24 + }, + { + "basename": "sync_order", + "code": "pdd/sync_order.py", + "prompt": "pdd/prompts/sync_order_python.prompt", + "meta": ".pdd/meta/sync_order_python.json", + "code_last": "2026-06-02T17:13:54-07:00", + "prompt_last": "2026-05-21T15:15:27-07:00", + "code_ahead": true, + "days_ahead": 12.08, + "churn_lines": 362, + "churn_commits": 5, + "both_commits": 2, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-02T22:49:32Z", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 693, + "rank": 25 + }, + { + "basename": "evidence_store", + "code": "pdd/evidence_store.py", + "prompt": "pdd/prompts/evidence_store_python.prompt", + "meta": ".pdd/meta/evidence_store_python.json", + "code_last": "2026-05-29T18:35:11-07:00", + "prompt_last": "2026-05-28T14:38:50-07:00", + "code_ahead": true, + "days_ahead": 1.16, + "churn_lines": 352, + "churn_commits": 3, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-05-29T18:35:11-07:00", + "last_prompt_only_date": "2026-05-28T14:38:50-07:00", + "conflict_risk": true, + "code_loc": 186, + "rank": 26 + }, + { + "basename": "agentic_split", + "code": "pdd/agentic_split.py", + "prompt": "pdd/prompts/agentic_split_python.prompt", + "meta": ".pdd/meta/agentic_split_python.json", + "code_last": "2026-05-25T15:39:43-07:00", + "prompt_last": "2026-05-07T20:02:18-07:00", + "code_ahead": true, + "days_ahead": 17.82, + "churn_lines": 343, + "churn_commits": 4, + "both_commits": 3, + "prompt_only_commits": 1, + "last_code_only_date": "2026-05-25T15:39:43-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 456, + "rank": 27 + }, + { + "basename": "story_regression", + "code": "pdd/story_regression.py", + "prompt": "pdd/prompts/story_regression_python.prompt", + "meta": ".pdd/meta/story_regression_python.json", + "code_last": "2026-07-02T12:08:00-07:00", + "prompt_last": "2026-06-29T12:31:20-07:00", + "code_ahead": true, + "days_ahead": 2.98, + "churn_lines": 338, + "churn_commits": 4, + "both_commits": 1, + "prompt_only_commits": 1, + "last_code_only_date": "2026-07-02T12:08:00-07:00", + "last_prompt_only_date": "2026-06-22T23:13:25Z", + "conflict_risk": false, + "code_loc": 362, + "rank": 28 + }, + { + "basename": "server/token_counter", + "code": "pdd/server/token_counter.py", + "prompt": "pdd/prompts/server/token_counter_python.prompt", + "meta": ".pdd/meta/server_token_counter_python.json", + "code_last": "2026-07-06T19:47:19-07:00", + "prompt_last": "2026-06-04T14:19:46-07:00", + "code_ahead": true, + "days_ahead": 32.23, + "churn_lines": 337, + "churn_commits": 6, + "both_commits": 4, + "prompt_only_commits": 2, + "last_code_only_date": "2026-07-06T19:47:19-07:00", + "last_prompt_only_date": "2026-05-25T15:52:33-07:00", + "conflict_risk": false, + "code_loc": 645, + "rank": 29 + }, + { + "basename": "architecture_include_validation", + "code": "pdd/architecture_include_validation.py", + "prompt": "pdd/prompts/architecture_include_validation_python.prompt", + "meta": ".pdd/meta/architecture_include_validation_python.json", + "code_last": "2026-05-27T20:33:13-07:00", + "prompt_last": "2026-05-27T17:19:07-07:00", + "code_ahead": true, + "days_ahead": 0.13, + "churn_lines": 332, + "churn_commits": 7, + "both_commits": 3, + "prompt_only_commits": 3, + "last_code_only_date": "2026-05-27T20:33:13-07:00", + "last_prompt_only_date": "2026-05-18T13:22:45-07:00", + "conflict_risk": false, + "code_loc": 770, + "rank": 30 + }, + { + "basename": "checkup_prompt_apply", + "code": "pdd/checkup_prompt_apply.py", + "prompt": "pdd/prompts/checkup_prompt_apply_python.prompt", + "meta": ".pdd/meta/checkup_prompt_apply_python.json", + "code_last": "2026-06-10T16:12:44-07:00", + "prompt_last": "2026-06-10T00:36:59-07:00", + "code_ahead": true, + "days_ahead": 0.65, + "churn_lines": 313, + "churn_commits": 2, + "both_commits": 2, + "prompt_only_commits": 0, + "last_code_only_date": "2026-06-10T16:12:44-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 332, + "rank": 31 + }, + { + "basename": "agentic_architecture_orchestrator", + "code": "pdd/agentic_architecture_orchestrator.py", + "prompt": "pdd/prompts/agentic_architecture_orchestrator_python.prompt", + "meta": ".pdd/meta/agentic_architecture_orchestrator_python.json", + "code_last": "2026-06-02T22:49:32Z", + "prompt_last": "2026-05-07T20:15:16Z", + "code_ahead": true, + "days_ahead": 26.11, + "churn_lines": 308, + "churn_commits": 9, + "both_commits": 1, + "prompt_only_commits": 4, + "last_code_only_date": "2026-06-02T22:49:32Z", + "last_prompt_only_date": "2026-05-07T20:15:16Z", + "conflict_risk": true, + "code_loc": 1946, + "rank": 32 + }, + { + "basename": "agentic_test_generate", + "code": "pdd/agentic_test_generate.py", + "prompt": "pdd/prompts/agentic_test_generate_python.prompt", + "meta": ".pdd/meta/agentic_test_generate_python.json", + "code_last": "2026-06-23T17:41:58-07:00", + "prompt_last": "2026-05-18T12:50:30-07:00", + "code_ahead": true, + "days_ahead": 36.2, + "churn_lines": 293, + "churn_commits": 5, + "both_commits": 3, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-23T17:41:58-07:00", + "last_prompt_only_date": "2026-05-17T18:17:01-07:00", + "conflict_risk": false, + "code_loc": 499, + "rank": 33 + }, + { + "basename": "checkup_interactive_session", + "code": "pdd/checkup_interactive_session.py", + "prompt": "pdd/prompts/checkup_interactive_session_python.prompt", + "meta": ".pdd/meta/checkup_interactive_session_python.json", + "code_last": "2026-06-09T15:08:22-07:00", + "prompt_last": "2026-06-09T12:22:58-07:00", + "code_ahead": true, + "days_ahead": 0.11, + "churn_lines": 260, + "churn_commits": 2, + "both_commits": 1, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-09T15:08:22-07:00", + "last_prompt_only_date": "2026-06-09T12:22:58-07:00", + "conflict_risk": true, + "code_loc": 130, + "rank": 34 + }, + { + "basename": "checkup_file_selection", + "code": "pdd/checkup_file_selection.py", + "prompt": "pdd/prompts/checkup_file_selection_python.prompt", + "meta": ".pdd/meta/checkup_file_selection_python.json", + "code_last": "2026-05-27T21:31:30-07:00", + "prompt_last": "2026-05-27T14:31:23-07:00", + "code_ahead": true, + "days_ahead": 0.29, + "churn_lines": 243, + "churn_commits": 3, + "both_commits": 1, + "prompt_only_commits": 0, + "last_code_only_date": "2026-05-27T21:31:30-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 259, + "rank": 35 + }, + { + "basename": "checkup_planner", + "code": "pdd/checkup_planner.py", + "prompt": "pdd/prompts/checkup_planner_python.prompt", + "meta": ".pdd/meta/checkup_planner_python.json", + "code_last": "2026-06-10T14:45:41-07:00", + "prompt_last": "2026-06-10T10:13:54-07:00", + "code_ahead": true, + "days_ahead": 0.19, + "churn_lines": 238, + "churn_commits": 4, + "both_commits": 0, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-10T14:45:41-07:00", + "last_prompt_only_date": "2026-06-10T10:13:54-07:00", + "conflict_risk": true, + "code_loc": 207, + "rank": 36 + }, + { + "basename": "core/errors", + "code": "pdd/core/errors.py", + "prompt": "pdd/prompts/core/errors_python.prompt", + "meta": ".pdd/meta/core_errors_python.json", + "code_last": "2026-07-06T16:17:24-07:00", + "prompt_last": "2026-06-20T13:56:42-07:00", + "code_ahead": true, + "days_ahead": 16.1, + "churn_lines": 232, + "churn_commits": 5, + "both_commits": 1, + "prompt_only_commits": 2, + "last_code_only_date": "2026-07-06T16:17:24-07:00", + "last_prompt_only_date": "2026-05-25T15:52:33-07:00", + "conflict_risk": false, + "code_loc": 259, + "rank": 37 + }, + { + "basename": "server/routes/architecture", + "code": "pdd/server/routes/architecture.py", + "prompt": "pdd/prompts/server/routes/architecture_python.prompt", + "meta": ".pdd/meta/server_routes_architecture_python.json", + "code_last": "2026-06-01T18:53:07-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 31.8, + "churn_lines": 227, + "churn_commits": 2, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-01T18:53:07-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 480, + "rank": 38 + }, + { + "basename": "checkup_simplify_engines", + "code": "pdd/checkup_simplify_engines.py", + "prompt": "pdd/prompts/checkup_simplify_engines_python.prompt", + "meta": ".pdd/meta/checkup_simplify_engines_python.json", + "code_last": "2026-05-28T14:46:46-07:00", + "prompt_last": "2026-05-28T14:01:52-07:00", + "code_ahead": true, + "days_ahead": 0.03, + "churn_lines": 203, + "churn_commits": 2, + "both_commits": 1, + "prompt_only_commits": 0, + "last_code_only_date": "2026-05-28T14:46:46-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 201, + "rank": 39 + }, + { + "basename": "path_resolution", + "code": "pdd/path_resolution.py", + "prompt": "pdd/prompts/path_resolution_python.prompt", + "meta": ".pdd/meta/path_resolution_python.json", + "code_last": "2026-05-26T20:22:50-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 25.86, + "churn_lines": 182, + "churn_commits": 8, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-26T20:22:50-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 188, + "rank": 40 + }, + { + "basename": "config_resolution", + "code": "pdd/config_resolution.py", + "prompt": "pdd/prompts/config_resolution_python.prompt", + "meta": ".pdd/meta/config_resolution_python.json", + "code_last": "2026-06-18T18:00:49-07:00", + "prompt_last": "2026-06-02T20:43:19Z", + "code_ahead": true, + "days_ahead": 16.18, + "churn_lines": 182, + "churn_commits": 6, + "both_commits": 1, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-18T18:00:49-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 201, + "rank": 41 + }, + { + "basename": "get_language", + "code": "pdd/get_language.py", + "prompt": "pdd/prompts/get_language_python.prompt", + "meta": ".pdd/meta/get_language_python.json", + "code_last": "2026-05-26T13:08:10-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 25.56, + "churn_lines": 128, + "churn_commits": 5, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-26T13:08:10-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 42, + "rank": 42 + }, + { + "basename": "get_test_command", + "code": "pdd/get_test_command.py", + "prompt": "pdd/prompts/get_test_command_python.prompt", + "meta": ".pdd/meta/get_test_command_python.json", + "code_last": "2026-05-26T13:08:10-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 25.56, + "churn_lines": 127, + "churn_commits": 6, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-26T13:08:10-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 123, + "rank": 43 + }, + { + "basename": "grounding_policy", + "code": "pdd/grounding_policy.py", + "prompt": "pdd/prompts/grounding_policy_python.prompt", + "meta": ".pdd/meta/grounding_policy_python.json", + "code_last": "2026-05-29T09:21:44-07:00", + "prompt_last": "2026-05-28T20:08:35-07:00", + "code_ahead": true, + "days_ahead": 0.55, + "churn_lines": 127, + "churn_commits": 2, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-05-29T09:21:44-07:00", + "last_prompt_only_date": "2026-05-28T20:08:35-07:00", + "conflict_risk": true, + "code_loc": 119, + "rank": 44 + }, + { + "basename": "commands/context", + "code": "pdd/commands/context.py", + "prompt": "pdd/prompts/commands/context_python.prompt", + "meta": ".pdd/meta/commands_context_python.json", + "code_last": "2026-06-17T14:11:15-07:00", + "prompt_last": "2026-06-12T15:38:36-07:00", + "code_ahead": true, + "days_ahead": 4.94, + "churn_lines": 121, + "churn_commits": 4, + "both_commits": 10, + "prompt_only_commits": 0, + "last_code_only_date": "2026-06-17T14:11:15-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 397, + "rank": 45 + }, + { + "basename": "commands/contracts", + "code": "pdd/commands/contracts.py", + "prompt": "pdd/prompts/commands/contracts_python.prompt", + "meta": ".pdd/meta/commands_contracts_python.json", + "code_last": "2026-06-01T20:53:52-07:00", + "prompt_last": "2026-05-27T12:05:21-07:00", + "code_ahead": true, + "days_ahead": 5.37, + "churn_lines": 106, + "churn_commits": 3, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-01T20:53:52-07:00", + "last_prompt_only_date": "2026-05-27T12:05:21-07:00", + "conflict_risk": true, + "code_loc": 94, + "rank": 46 + }, + { + "basename": "auto_include", + "code": "pdd/auto_include.py", + "prompt": "pdd/prompts/auto_include_python.prompt", + "meta": ".pdd/meta/auto_include_python.json", + "code_last": "2026-06-02T19:12:39-07:00", + "prompt_last": "2026-06-02T22:49:32Z", + "code_ahead": true, + "days_ahead": 0.14, + "churn_lines": 106, + "churn_commits": 2, + "both_commits": 0, + "prompt_only_commits": 4, + "last_code_only_date": "2026-06-02T19:12:39-07:00", + "last_prompt_only_date": "2026-06-02T22:49:32Z", + "conflict_risk": true, + "code_loc": 551, + "rank": 47 + }, + { + "basename": "change_main", + "code": "pdd/change_main.py", + "prompt": "pdd/prompts/change_main_python.prompt", + "meta": ".pdd/meta/change_main_python.json", + "code_last": "2026-06-10T14:45:41-07:00", + "prompt_last": "2026-05-07T17:01:09-07:00", + "code_ahead": true, + "days_ahead": 33.91, + "churn_lines": 92, + "churn_commits": 11, + "both_commits": 1, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-10T14:45:41-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 641, + "rank": 48 + }, + { + "basename": "operation_log", + "code": "pdd/operation_log.py", + "prompt": "pdd/prompts/operation_log_python.prompt", + "meta": ".pdd/meta/operation_log_python.json", + "code_last": "2026-06-11T17:45:56-07:00", + "prompt_last": "2026-06-03T02:01:41Z", + "code_ahead": true, + "days_ahead": 8.95, + "churn_lines": 89, + "churn_commits": 3, + "both_commits": 4, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-11T17:45:56-07:00", + "last_prompt_only_date": "2026-06-01T18:25:33Z", + "conflict_risk": false, + "code_loc": 857, + "rank": 49 + }, + { + "basename": "checkup_gates", + "code": "pdd/checkup_gates.py", + "prompt": "pdd/prompts/checkup_gates_python.prompt", + "meta": ".pdd/meta/checkup_gates_python.json", + "code_last": "2026-06-08T17:50:39-07:00", + "prompt_last": "2026-06-06T12:31:51-07:00", + "code_ahead": true, + "days_ahead": 2.22, + "churn_lines": 79, + "churn_commits": 5, + "both_commits": 11, + "prompt_only_commits": 0, + "last_code_only_date": "2026-06-08T17:50:39-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 3975, + "rank": 50 + }, + { + "basename": "commands/utility", + "code": "pdd/commands/utility.py", + "prompt": "pdd/prompts/commands/utility_python.prompt", + "meta": ".pdd/meta/commands_utility_python.json", + "code_last": "2026-05-27T18:34:51-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 26.79, + "churn_lines": 75, + "churn_commits": 3, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-05-27T18:34:51-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 138, + "rank": 51 + }, + { + "basename": "context_generator_main", + "code": "pdd/context_generator_main.py", + "prompt": "pdd/prompts/context_generator_main_python.prompt", + "meta": ".pdd/meta/context_generator_main_python.json", + "code_last": "2026-06-01T14:54:50-07:00", + "prompt_last": "2026-06-01T14:22:07-07:00", + "code_ahead": true, + "days_ahead": 0.02, + "churn_lines": 67, + "churn_commits": 3, + "both_commits": 6, + "prompt_only_commits": 6, + "last_code_only_date": "2026-06-01T14:54:50-07:00", + "last_prompt_only_date": "2026-06-01T19:05:26Z", + "conflict_risk": true, + "code_loc": 302, + "rank": 52 + }, + { + "basename": "detect_change_main", + "code": "pdd/detect_change_main.py", + "prompt": "pdd/prompts/detect_change_main_python.prompt", + "meta": ".pdd/meta/detect_change_main_python.json", + "code_last": "2026-06-11T11:32:23-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 41.49, + "churn_lines": 60, + "churn_commits": 1, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-11T11:32:23-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 134, + "rank": 53 + }, + { + "basename": "server/__init__", + "code": "pdd/commands/__init__.py", + "prompt": "pdd/prompts/server/__init___python.prompt", + "meta": null, + "code_last": "2026-07-09T04:59:18-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 69.22, + "churn_lines": 46, + "churn_commits": 18, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-07-09T04:59:18-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 68, + "rank": 54 + }, + { + "basename": "server/routes/__init__", + "code": "pdd/commands/__init__.py", + "prompt": "pdd/prompts/server/routes/__init___python.prompt", + "meta": null, + "code_last": "2026-07-09T04:59:18-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 69.22, + "churn_lines": 46, + "churn_commits": 18, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-07-09T04:59:18-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 68, + "rank": 55 + }, + { + "basename": "cli", + "code": "pdd/cli.py", + "prompt": "pdd/prompts/cli_python.prompt", + "meta": null, + "code_last": "2026-06-05T14:24:53-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 35.61, + "churn_lines": 44, + "churn_commits": 10, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-05T14:24:53-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 84, + "rank": 56 + }, + { + "basename": "preprocess_main", + "code": "pdd/preprocess_main.py", + "prompt": "pdd/prompts/preprocess_main_python.prompt", + "meta": ".pdd/meta/preprocess_main_python.json", + "code_last": "2026-06-03T14:03:59-07:00", + "prompt_last": "2026-06-02T22:49:32Z", + "code_ahead": true, + "days_ahead": 0.93, + "churn_lines": 39, + "churn_commits": 4, + "both_commits": 3, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-03T14:03:59-07:00", + "last_prompt_only_date": "2026-05-05T23:50:27-07:00", + "conflict_risk": false, + "code_loc": 156, + "rank": 57 + }, + { + "basename": "commands/__init__", + "code": "pdd/commands/__init__.py", + "prompt": "pdd/prompts/commands/__init___python.prompt", + "meta": null, + "code_last": "2026-07-09T04:59:18-07:00", + "prompt_last": "2026-07-03T09:56:47-07:00", + "code_ahead": true, + "days_ahead": 5.79, + "churn_lines": 38, + "churn_commits": 15, + "both_commits": 3, + "prompt_only_commits": 11, + "last_code_only_date": "2026-07-09T04:59:18-07:00", + "last_prompt_only_date": "2026-07-03T09:56:47-07:00", + "conflict_risk": true, + "code_loc": 68, + "rank": 58 + }, + { + "basename": "agentic_fix", + "code": "pdd/agentic_fix.py", + "prompt": "pdd/prompts/agentic_fix_python.prompt", + "meta": ".pdd/meta/agentic_fix_python.json", + "code_last": "2026-06-23T17:41:58-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 53.75, + "churn_lines": 35, + "churn_commits": 3, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-23T17:41:58-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 461, + "rank": 59 + }, + { + "basename": "cmd_test_main", + "code": "pdd/cmd_test_main.py", + "prompt": "pdd/prompts/cmd_test_main_python.prompt", + "meta": ".pdd/meta/cmd_test_main_python.json", + "code_last": "2026-06-03T14:34:08-07:00", + "prompt_last": "2026-06-03T02:01:41Z", + "code_ahead": true, + "days_ahead": 0.81, + "churn_lines": 25, + "churn_commits": 2, + "both_commits": 3, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-03T14:34:08-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 621, + "rank": 60 + }, + { + "basename": "get_extension", + "code": "pdd/get_extension.py", + "prompt": "pdd/prompts/get_extension_python.prompt", + "meta": ".pdd/meta/get_extension_python.json", + "code_last": "2026-05-26T13:08:10-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 25.56, + "churn_lines": 20, + "churn_commits": 2, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-26T13:08:10-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 65, + "rank": 61 + }, + { + "basename": "get_run_command", + "code": "pdd/get_run_command.py", + "prompt": "pdd/prompts/get_run_command_python.prompt", + "meta": ".pdd/meta/get_run_command_python.json", + "code_last": "2026-05-26T13:08:10-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 25.56, + "churn_lines": 20, + "churn_commits": 2, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-26T13:08:10-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 75, + "rank": 62 + }, + { + "basename": "postprocess_0", + "code": "pdd/postprocess_0.py", + "prompt": "pdd/prompts/postprocess_0_python.prompt", + "meta": ".pdd/meta/postprocess_0_python.json", + "code_last": "2026-05-25T15:39:43-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 24.67, + "churn_lines": 20, + "churn_commits": 2, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-25T15:39:43-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 52, + "rank": 63 + }, + { + "basename": "pddrc_initializer", + "code": "pdd/pddrc_initializer.py", + "prompt": "pdd/prompts/pddrc_initializer_python.prompt", + "meta": ".pdd/meta/pddrc_initializer_python.json", + "code_last": "2026-05-25T15:39:43-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 24.67, + "churn_lines": 19, + "churn_commits": 3, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-25T15:39:43-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 522, + "rank": 64 + }, + { + "basename": "agentic_update", + "code": "pdd/agentic_update.py", + "prompt": "pdd/prompts/agentic_update_python.prompt", + "meta": ".pdd/meta/agentic_update_python.json", + "code_last": "2026-06-23T17:41:58-07:00", + "prompt_last": "2026-05-23T19:18:25Z", + "code_ahead": true, + "days_ahead": 31.22, + "churn_lines": 10, + "churn_commits": 2, + "both_commits": 1, + "prompt_only_commits": 5, + "last_code_only_date": "2026-06-23T17:41:58-07:00", + "last_prompt_only_date": "2026-05-23T19:18:25Z", + "conflict_risk": true, + "code_loc": 578, + "rank": 65 + }, + { + "basename": "agentic_crash", + "code": "pdd/agentic_crash.py", + "prompt": "pdd/prompts/agentic_crash_python.prompt", + "meta": ".pdd/meta/agentic_crash_python.json", + "code_last": "2026-06-23T17:41:58-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 53.75, + "churn_lines": 9, + "churn_commits": 1, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-23T17:41:58-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 562, + "rank": 66 + }, + { + "basename": "template_registry", + "code": "pdd/template_registry.py", + "prompt": "pdd/prompts/template_registry_python.prompt", + "meta": ".pdd/meta/template_registry_python.json", + "code_last": "2026-05-25T18:10:25-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 24.77, + "churn_lines": 8, + "churn_commits": 1, + "both_commits": 0, + "prompt_only_commits": 2, + "last_code_only_date": "2026-05-25T18:10:25-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 258, + "rank": 67 + }, + { + "basename": "failure_classification", + "code": "pdd/failure_classification.py", + "prompt": "pdd/prompts/failure_classification_python.prompt", + "meta": ".pdd/meta/failure_classification_python.json", + "code_last": "2026-06-16T00:56:22Z", + "prompt_last": "2026-06-15T22:08:50Z", + "code_ahead": true, + "days_ahead": 0.12, + "churn_lines": 7, + "churn_commits": 1, + "both_commits": 0, + "prompt_only_commits": 3, + "last_code_only_date": "2026-06-16T00:56:22Z", + "last_prompt_only_date": "2026-06-15T22:08:50Z", + "conflict_risk": true, + "code_loc": 109, + "rank": 68 + }, + { + "basename": "server/routes/commands", + "code": "pdd/server/routes/commands.py", + "prompt": "pdd/prompts/server/routes/commands_python.prompt", + "meta": ".pdd/meta/server_routes_commands_python.json", + "code_last": "2026-05-07T21:31:28-07:00", + "prompt_last": "2026-04-30T23:40:47-07:00", + "code_ahead": true, + "days_ahead": 6.91, + "churn_lines": 6, + "churn_commits": 2, + "both_commits": 0, + "prompt_only_commits": 1, + "last_code_only_date": "2026-05-07T21:31:28-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": true, + "code_loc": 929, + "rank": 69 + }, + { + "basename": "agentic_bug", + "code": "pdd/agentic_bug.py", + "prompt": "pdd/prompts/agentic_bug_python.prompt", + "meta": ".pdd/meta/agentic_bug_python.json", + "code_last": "2026-06-01T20:48:24-07:00", + "prompt_last": "2026-05-25T16:15:33-07:00", + "code_ahead": true, + "days_ahead": 7.19, + "churn_lines": 5, + "churn_commits": 2, + "both_commits": 1, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-01T20:48:24-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 329, + "rank": 70 + }, + { + "basename": "commands/misc", + "code": "pdd/commands/misc.py", + "prompt": "pdd/prompts/commands/misc_python.prompt", + "meta": ".pdd/meta/commands_misc_python.json", + "code_last": "2026-06-01T20:31:32-07:00", + "prompt_last": "2026-05-29T01:16:35Z", + "code_ahead": true, + "days_ahead": 4.09, + "churn_lines": 5, + "churn_commits": 1, + "both_commits": 1, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-01T20:31:32-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 98, + "rank": 71 + }, + { + "basename": "cli_status", + "code": "pdd/cli_status.py", + "prompt": "pdd/prompts/cli_status_python.prompt", + "meta": ".pdd/meta/cli_status_python.json", + "code_last": "2026-06-12T15:38:36-07:00", + "prompt_last": "2026-06-11T11:32:23-07:00", + "code_ahead": true, + "days_ahead": 1.17, + "churn_lines": 4, + "churn_commits": 1, + "both_commits": 1, + "prompt_only_commits": 0, + "last_code_only_date": "2026-06-12T15:38:36-07:00", + "last_prompt_only_date": null, + "conflict_risk": false, + "code_loc": 268, + "rank": 72 + }, + { + "basename": "split", + "code": "pdd/split.py", + "prompt": "pdd/prompts/split_python.prompt", + "meta": ".pdd/meta/split_python.json", + "code_last": "2026-06-02T22:49:32Z", + "prompt_last": "2026-05-06T00:19:27-07:00", + "code_ahead": true, + "days_ahead": 27.65, + "churn_lines": 2, + "churn_commits": 1, + "both_commits": 0, + "prompt_only_commits": 4, + "last_code_only_date": "2026-06-02T22:49:32Z", + "last_prompt_only_date": "2026-05-06T00:19:27-07:00", + "conflict_risk": true, + "code_loc": 131, + "rank": 73 + }, + { + "basename": "core/utils", + "code": "pdd/core/utils.py", + "prompt": "pdd/prompts/core/utils_python.prompt", + "meta": ".pdd/meta/core_utils_python.json", + "code_last": "2026-06-05T15:31:37-07:00", + "prompt_last": "2026-05-25T15:52:33-07:00", + "code_ahead": true, + "days_ahead": 10.99, + "churn_lines": 2, + "churn_commits": 1, + "both_commits": 1, + "prompt_only_commits": 1, + "last_code_only_date": "2026-06-05T15:31:37-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 118, + "rank": 74 + }, + { + "basename": "agentic_test", + "code": "pdd/agentic_test.py", + "prompt": "pdd/prompts/agentic_test_python.prompt", + "meta": ".pdd/meta/agentic_test_python.json", + "code_last": "2026-06-01T20:48:24-07:00", + "prompt_last": "2026-05-25T16:15:33-07:00", + "code_ahead": true, + "days_ahead": 7.19, + "churn_lines": 1, + "churn_commits": 1, + "both_commits": 1, + "prompt_only_commits": 2, + "last_code_only_date": "2026-06-01T20:48:24-07:00", + "last_prompt_only_date": "2026-04-30T23:40:47-07:00", + "conflict_risk": false, + "code_loc": 312, + "rank": 75 + } + ] +} From 2be92718a297ce97b037f26284b24699d7e7ae56 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:23:59 -0700 Subject: [PATCH 16/30] Prompt catch-up: back-propagate server/token_counter (A2 pilot 1) pdd update (agentic, provider=google) back-propagated code->prompt for the code-ahead unit server/token_counter (queue rank 28, non-conflict: prompt last synced with code by joint commit c1db8fc25, then code drifted 32d). Prompt gains a structured interface covering all 8 public functions + CostEstimate/TokenMetrics; internal NamedTuple ModelPricing stays undeclared (was never in the prompt, not dropped). Code untouched; tests/server/test_token_counter.py 42 passed. Re-stamped via scripts/stamp_fingerprints.py to the subdir-qualified meta .pdd/meta/server_token_counter_python.json (pdd update itself wrote a stray leaf-named .pdd/meta/token_counter_python.json -- removed; see report). --check clean. Co-Authored-By: Claude --- .pdd/meta/server_token_counter_python.json | 4 +- .../server/token_counter_python.prompt | 116 ++++++++++-------- 2 files changed, 70 insertions(+), 50 deletions(-) diff --git a/.pdd/meta/server_token_counter_python.json b/.pdd/meta/server_token_counter_python.json index 48b78044e9..3e53e26aa6 100644 --- a/.pdd/meta/server_token_counter_python.json +++ b/.pdd/meta/server_token_counter_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.455051+00:00", + "timestamp": "2026-07-09T20:23:32.601502+00:00", "command": "fix", - "prompt_hash": "2487fd62e2c8a29e5a404d43df9f63df63eabae82b7e6bbdab9804df9fa8be18", + "prompt_hash": "af89232b742fe3ce556d33ac961e0a0342711e50c8305242b78d5406d3aee4db", "code_hash": "847ac13e3804c451aca64652877940c06b72c2fc33edc00232f1d4aa16c957e8", "example_hash": "75a40b397db75482e743fc7ec0ec26ae09650746111abb48a941e8d58214c9a5", "test_hash": "f661f43b95b469139c1c46b8e0091a7fdf81a993ff73ab5331f8c13c8f6a1984", diff --git a/pdd/prompts/server/token_counter_python.prompt b/pdd/prompts/server/token_counter_python.prompt index bd5c175968..a4bcbd60ad 100644 --- a/pdd/prompts/server/token_counter_python.prompt +++ b/pdd/prompts/server/token_counter_python.prompt @@ -6,11 +6,13 @@ "module": { "functions": [ {"name": "count_tokens", "signature": "(text: str, model: str = \"gpt-4o\") -> int", "returns": "int"}, + {"name": "count_tokens_for_messages", "signature": "(messages: Any, model: str = \"gpt-4o\") -> int", "returns": "int"}, {"name": "get_context_limit", "signature": "(model: str) -> Optional[int]", "returns": "Optional[int]"}, - {"name": "estimate_cost", "signature": "(token_count, model, pricing_csv) -> Optional[CostEstimate]", "returns": "Optional[CostEstimate]"}, - {"name": "estimate_completion_cost", "signature": "(input_tokens, predicted_output_tokens, model, pricing_csv) -> Optional[CostEstimate]", "returns": "Optional[CostEstimate]"}, + {"name": "get_max_output_tokens", "signature": "(model: str) -> Optional[int]", "returns": "Optional[int]"}, + {"name": "estimate_cost", "signature": "(token_count: int, model: str, pricing_csv: Optional[Union[str, Path]] = None) -> Optional[CostEstimate]", "returns": "Optional[CostEstimate]"}, + {"name": "estimate_completion_cost", "signature": "(input_tokens: int, predicted_output_tokens: int, model: str, pricing_csv: Optional[Union[str, Path]] = None) -> Optional[CostEstimate]", "returns": "Optional[CostEstimate]"}, {"name": "default_pricing_csv", "signature": "() -> Optional[Path]", "returns": "Optional[Path]"}, - {"name": "get_token_metrics", "signature": "(text, model, pricing_csv) -> TokenMetrics", "returns": "TokenMetrics"} + {"name": "get_token_metrics", "signature": "(text: str, model: str = \"claude-sonnet-4-20250514\", pricing_csv: Optional[Path] = None) -> TokenMetrics", "returns": "TokenMetrics"} ] } } @@ -19,62 +21,80 @@ % You are an expert Python engineer. Create a `token_counter` module for token counting and cost estimation. % Role & Scope -A utility module that counts tokens and looks up model context windows using litellm, and estimates costs from pricing CSV data. Used by the PDD server for prompt/context analysis. +A utility module that counts tokens, looks up model limits via litellm, and estimates costs from pricing CSV data. Used by the PDD server for prompt/context analysis. context/python_preamble.prompt % Requirements 1. Function: `count_tokens(text: str, model: str = "gpt-4o") -> int` - Use `litellm.token_counter(model=model, messages=[{"role": "user", "content": text}])` - - Fall back to tiktoken cl100k_base encoding if litellm raises any exception - - Return 0 for empty text + - Protect all litellm calls with a daemon-thread timeout (default 5.0s, configured via package-internal `_LITELLM_CALL_TIMEOUT_SEC` to prevent blocking OAuth provider-detection hangs). + - Fall back to tiktoken cl100k_base encoding if litellm raises any exception or times out. + - Return 0 for empty or None text. + +1a. Function: `count_tokens_for_messages(messages: Any, model: str = "gpt-4o") -> int` + - Use `litellm.token_counter` with the provided messages list. + - Protect with the daemon-thread timeout, falling back to tiktoken cl100k_base on error/timeout. + - Best-effort flattening of messages to a single string on fallback. + 2. Function: `get_context_limit(model: str) -> Optional[int]` - - Use `litellm.get_model_info(model)["max_input_tokens"]` to look up the input context window - - Return `None` if litellm raises any exception (unknown model — caller should skip validation) - - Do NOT use a hardcoded MODEL_CONTEXT_LIMITS dict + - Use `litellm.get_model_info(model)["max_input_tokens"]`. + - Protect with the daemon-thread timeout. + - Return `None` if litellm raises any exception or times out (caller should skip context-window validation). + - Do NOT use a hardcoded MODEL_CONTEXT_LIMITS dict. + +2a. Function: `get_max_output_tokens(model: str) -> Optional[int]` + - Get the max completion token budget via `litellm.get_model_info(model)["max_output_tokens"]`. + - Protect with the daemon-thread timeout; return None if unknown, times out, raises, or if limit <= 0. + 3. Function: `estimate_cost(token_count, model, pricing_csv) -> Optional[CostEstimate]` - - Preserve this existing input-only API for current callers - - Treat `token_count` as input tokens and do not require callers to provide output tokens - - Accept `pricing_csv` as either a `pathlib.Path` or a string path - - Use rows with a valid input rate even when an older CSV lacks an output rate + - Preserve this input-only API for current callers (treating `token_count` as input tokens). + - Accept `pricing_csv` as either a `pathlib.Path` or a string path. + - Use rows with a valid input rate even when an older CSV lacks an output rate. + 4. Function: `estimate_completion_cost(input_tokens, predicted_output_tokens, model, pricing_csv) -> Optional[CostEstimate]` - - Use `(input_tokens / 1_000_000) * input_rate + (predicted_output_tokens / 1_000_000) * output_rate` - - Return input cost, output cost, and total cost for deterministic pre-flight previews - - Accept `pricing_csv` as either a `pathlib.Path` or a string path - - When `pricing_csv` is None, resolve the canonical CSV via `default_pricing_csv()` so previews work without an explicit path; an explicitly supplied path is used as-is and never silently replaced by the default - - Require both valid input and valid output rates; return None when output pricing is absent + - Use `(input_tokens / 1_000_000) * input_rate + (predicted_output_tokens / 1_000_000) * output_rate`. + - Require both valid input and valid output rates; return None when output pricing is absent or None. + - Accept `pricing_csv` as either a `pathlib.Path` or a string path. + - When `pricing_csv` is None, resolve the canonical CSV via `default_pricing_csv()`; an explicitly supplied path is used as-is and never replaced by the default. + 4a. Function: `default_pricing_csv() -> Optional[pathlib.Path]` - - Return the first existing pricing CSV in order: `$HOME/.pdd/llm_model.csv`, then `/.pdd/llm_model.csv`, then the bundled `pdd/data/llm_model.csv` (resolve the bundled path relative to this module: `pdd/server/` -> `pdd/data/`) - - Return None when none exist, preserving the "cost is explicitly unknown" contract - - Only `estimate_completion_cost` falls back to this default; `estimate_cost` and `get_token_metrics` keep treating a None `pricing_csv` as "no pricing" -5. Function: `get_token_metrics(text, model, pricing_csv) -> TokenMetrics` combining all metrics -6. Dataclass `CostEstimate`: input_cost, output_cost, total_cost, model, matched_model, tokens, input_tokens, output_tokens, cost_per_million, input_cost_per_million, output_cost_per_million, currency (default USD) - - Preserve existing caller expectations for `input_cost`, `tokens`, and `cost_per_million` - - For input-only estimates, `tokens` remains the input token count and `cost_per_million` remains the input rate -7. Dataclass `TokenMetrics`: token_count, context_limit (Optional[int]), context_usage_percent (Optional[float]), cost_estimate -8. Both dataclasses have `to_dict()` methods for serialization -9. `CostEstimate.to_dict()` includes all new input/output/total fields and preserves legacy keys so existing API models and tests remain compatible - - Also expose `input_rate_per_million` and `output_rate_per_million` keys (aliases of `input_cost_per_million`/`output_cost_per_million`) so estimate-mode consumers that read per-million rates work against the single canonical `CostEstimate` -10. Pricing loaded from CSV with columns: model, input, output - - `input` and `output` are USD costs per million tokens - - Missing, blank, or invalid input pricing makes that row unavailable for cost estimation - - Missing, blank, or invalid output pricing makes that row unavailable for output-inclusive completion estimates, but must not break the legacy input-only `estimate_cost` API - - Explicit zero input or output pricing is valid known pricing, not unknown pricing - - Do not infer prices from another row when a row is malformed -11. Model matching for cost: exact match first, then conservative partial/substring match against valid priced rows only -12. Unknown model pricing returns None; do NOT fall back to default model prices because that invents a cost -13. Unknown models, missing pricing CSVs, and unavailable pricing rows still allow token counts and context metrics through `get_token_metrics`, but `cost_estimate` is explicitly None -14. Cache pricing data with lru_cache; do NOT cache litellm calls (litellm has its own cache) + - Return the first existing pricing CSV in order: `$HOME/.pdd/llm_model.csv`, then `/.pdd/llm_model.csv`, then the bundled `pdd/data/llm_model.csv` (resolved relative to this module: `pdd/server/` -> `pdd/data/`). + - Return None when none exist. + - Only `estimate_completion_cost` falls back to this default; `estimate_cost` and `get_token_metrics` keep treating a None `pricing_csv` as "no pricing". + +5. Function: `get_token_metrics(text, model, pricing_csv) -> TokenMetrics` combining all metrics. + +6. Dataclass `CostEstimate`: input_cost, output_cost, total_cost, model, matched_model, tokens, input_tokens, output_tokens, cost_per_million, input_cost_per_million, output_cost_per_million, currency (default USD). + - Populate compatibility/default fields during initialization if not provided (e.g. `total_cost = input_cost + output_cost`, `matched_model = model`, `input_tokens = tokens`, `output_tokens = 0`, `input_cost_per_million = cost_per_million`). + +7. Dataclass `TokenMetrics`: token_count, context_limit (Optional[int]), context_usage_percent (Optional[float]), cost_estimate. + +8. Both dataclasses have `to_dict()` methods for serialization. + - Round floats in dictionary serialization (`input_cost`, `output_cost`, `total_cost` to 6 decimal places, `context_usage_percent` to 2 decimal places). + - `CostEstimate.to_dict()` includes legacy keys and exposes `input_rate_per_million` and `output_rate_per_million` (aliases of `input_cost_per_million`/`output_cost_per_million`). + +9. Pricing loaded from CSV with columns: provider, model, input, output, interactive_only. + - `input` and `output` are USD costs per million tokens. + - Missing, blank, or invalid input pricing makes that row unavailable for cost estimation. + - Missing, blank, or invalid output pricing makes that row unavailable for output-inclusive completion estimates, but must not break the legacy input-only `estimate_cost` API. + - Genuinely free/local rows (e.g. `lm_studio`, `ollama`, `local` providers/prefixes, or model containing "local"/"free") with zero rates are valid known free prices. + - Subscription-backed zero rates (e.g. `Github Copilot`, `OpenAI ChatGPT`, `Z.AI Coding Plan` providers/prefixes, or `interactive_only=True` rows with zero prices) are treated as unknown (return None cost estimate). + - Genuinely paid rows take precedence over zero-rate rows for the same model ID (first non-zero entry wins). + - Do not infer prices from another row when a row is malformed. + +10. Model matching for cost: + - Exact match first (case-insensitive). + - Conservative matching: allows matching a provider-qualified requested model (e.g. `openai/gpt-4o`) to an unqualified CSV model (e.g. `gpt-4o`), or base name with a numeric suffix (e.g. matching `gpt-4-0613` to `gpt-4`). + - MUST NOT allow a bare requested model name to borrow/match a provider-scoped CSV model (e.g. requested `gpt-4o` must NOT match `openai/gpt-4o` or `azure/gpt-4o`). + - Unknown model pricing returns None; do NOT fall back to default model prices. + +11. Unknown models, missing pricing CSVs, and unavailable pricing rows still allow token counts and context metrics through `get_token_metrics`, but `cost_estimate` is explicitly None. + +12. Cache pricing data loading with `lru_cache(maxsize=1)`. Do NOT cache litellm calls. % Dependencies -- litellm: for token counting and context window lookup (primary) +- litellm: for token counting, message token counting, and context window lookup (primary) - tiktoken: fallback for token counting only -- CSV file at .pdd/llm_model.csv for pricing data using the PDD llm_model.csv shape with at least model,input,output +- CSV file at .pdd/llm_model.csv for pricing data - Tests should use deterministic fixture CSV rows rather than relying on live user pricing files - -% Instructions -- `get_context_limit` returning None means the model is unknown — callers must skip context validation, not raise an error -- Context usage percent is None when context_limit is None -- Input-only cost calculation: (token_count / 1_000_000) * input_cost_per_million -- Completion cost calculation: input cost plus output cost using separate input and output rates -- Context usage is percentage: (tokens / limit) * 100 From 1d4394deb348a67c187a47a32a0f149b0ecfca7e Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:28:32 -0700 Subject: [PATCH 17/30] Prompt catch-up: back-propagate commands/modify (A2 pilot 2) pdd update (agentic, provider=google) back-propagated code->prompt for the code-ahead unit commands/modify (queue rank 22, non-conflict). Detector marks it non-conflict because its most recent RAW prompt touch is the joint commit 7f9e46c66 (code+prompt together); note git log -- hides that commit via history simplification, so raw per-commit numstat is the correct signal. All 3 public commands (split, change, update) retained. Code untouched; tests/commands/test_modify.py 46 passed. Re-stamped to subdir-qualified .pdd/meta/commands_modify_python.json; removed the stray leaf-named .pdd/meta/modify_python.json pdd update wrote. --check clean. Co-Authored-By: Claude --- .pdd/meta/commands_modify_python.json | 4 ++-- pdd/prompts/commands/modify_python.prompt | 24 +++++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.pdd/meta/commands_modify_python.json b/.pdd/meta/commands_modify_python.json index 8ed83b0ff8..d6ee9b7fc9 100644 --- a/.pdd/meta/commands_modify_python.json +++ b/.pdd/meta/commands_modify_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.347761+00:00", + "timestamp": "2026-07-09T20:28:15.207028+00:00", "command": "fix", - "prompt_hash": "2f9a78de992e04c361ee0559f689b4c4b1f5d46f84ccf773ba208ebc0ea80a5b", + "prompt_hash": "bfe68bce6a639f9ebde548e3e0812a7632082c6988f0441bc1f51d2466741419", "code_hash": "666d20da91b1037b24aa9a5c9f10684417ac31ad9c5c765c7b59d50916db7a99", "example_hash": "84edd899e3202fe13dc2e9437505a85552ec870b325e5628727d7202371d8134", "test_hash": "86242f8ba65ee0bd4c5224b7c39f243c851a66a8812d4747d543e77fda043707", diff --git a/pdd/prompts/commands/modify_python.prompt b/pdd/prompts/commands/modify_python.prompt index 8a5855df99..9ac836679c 100644 --- a/pdd/prompts/commands/modify_python.prompt +++ b/pdd/prompts/commands/modify_python.prompt @@ -43,33 +43,41 @@ This module provides Click commands (`split`, `change`, `update`) for prompt man 3. **change**: - Doc: "Modify an input prompt file based on a change prompt or issue." - - Args: `args` (nargs=-1). Options: `--manual`, `--budget` (5.0), `--output`, `--csv`, `--timeout-adder` (0.0), `--no-github-state`, `--clean-restart`, `--prompt-checkup {warn,strict}`, `--no-prompt-checkup`, `--interactive`. - - Store the prompt-checkup options in `ctx.obj` using keys compatible with workflow prompt gates (`prompt_checkup`, `no_prompt_checkup`, `interactive`) before calling agentic or manual change logic. + - Args: `args` (nargs=-1). Options: `--manual`, `--budget` (5.0), `--output`, `--csv`, `--timeout-adder` (0.0), `--no-github-state`, `--clean-restart`, `--prompt-checkup {warn,strict}`, `--no-prompt-checkup`, `--interactive`, `--apply`, `--preflight`, `--json` (param as_json), `--evidence` (flag, default False). + - Store the prompt-checkup options (`prompt_checkup`, `no_prompt_checkup`, `interactive`, `apply`) in `ctx.obj` before calling change logic. + - **`--preflight` / `--json`**: When `--preflight` is set, call `build_report(consumer="change-preflight")` from `..continuous_sync`. If `as_json` is True, set `ctx.obj["_suppress_result_summary"] = True` and print JSON formatted report with `indent=2, sort_keys=True`. Otherwise, print formatted summary string with fields: `metadata_stale`, `conflicts`, `unbaselined`, `failures`. Returns `None`. - **Agentic (default)**: 1 arg (issue_url). Calls `run_agentic_change(use_github_state=not no_github_state, clean_restart=clean_restart, ...)`. When `--no-github-state` is set, temporarily set environment variable `PDD_NO_GITHUB_STATE=1` for the duration of the agentic change call and restore the previous value afterward; this disables both hidden GitHub state persistence and visible orchestrator step comments. Displays: Status, Message, Cost (4 decimals), Model, and changed files. Suppress the "Model: ..." line if the model name is empty, "unknown", or "N/A" (case-insensitive). Exit(1) on failure. - - After a successful agentic or manual change that writes prompt files, call `maybe_run_workflow_prompt_gate(...)` with the changed prompt paths, the resolved project root, `prompt_checkup`, `no_prompt_checkup`, and `interactive`. If the gate returns a blocking result, print its message and raise `click.exceptions.Exit(exit_code)` so code generation/modification does not continue after unresolved strict prompt findings. + - After a successful agentic or manual change that writes prompt files, call `maybe_run_workflow_prompt_gate(...)` with the changed prompt paths, the resolved project root, `prompt_checkup`, `no_prompt_checkup`, `interactive`, and `apply`. If the gate returns a blocking result, print its message and raise `click.exceptions.Exit(exit_code)` so code generation/modification does not continue after unresolved strict prompt findings. - `--interactive` only enables interactive prompt repair when explicitly passed, and must require a TTY through the shared prompt-gate/checkup path. In strict mode, interactive repair must be followed by a deterministic re-check; unresolved findings after skip, preview-only, rejected patch, or no-op repair must fail closed. - **`--clean-restart` flag** (agentic mode only): Boolean flag (default `False`). Help text: "Discard any persisted solving state for this issue and start a fresh full pdd-issue flow from the default base branch, ignoring any previously generated change/issue-N branch artifacts. Use when recovering from a stopped or wrong-model run." Validation: MUST raise `click.UsageError` when combined with `--manual` ("--clean-restart is only valid in agentic mode and cannot be used with --manual") or when the single agentic argument is not a GitHub issue URL ("--clean-restart can only be used with an agentic GitHub issue URL."). When set, forwarded to `run_agentic_change` as `clean_restart=True`; otherwise passes `clean_restart=False`. - **Manual (`--manual`)**: - - `--csv`: 2 args (change_file, input_code: directory). - - Standard: 3 args (change_file, input_code: file, input_prompt). - - Validation: `input_code` must match expected type (dir for CSV, file otherwise). Check existence for all files. + - `--csv`: 2 args (change_file, input_code: directory). Raises `click.UsageError("Cannot use --csv and specify an INPUT_PROMPT_FILE simultaneously.")` if 3 arguments are provided. Raises `click.UsageError("INPUT_CODE must be a directory when using --csv")` if `input_code` is a file. If not 2 args, raises "CSV mode requires 2 arguments: CSV_FILE CODE_DIRECTORY". + - Standard: 3 args (change_file, input_code: file, input_prompt). Raises `click.UsageError("INPUT_PROMPT_FILE is required when not using --csv")` if 2 arguments are provided. Raises `click.UsageError("INPUT_CODE must be a file when not using --csv")` if `input_code` is a directory. If other arg count, raises "Manual mode requires 3 arguments: CHANGE_PROMPT INPUT_CODE INPUT_PROMPT". + - Validation: Check existence for all files (`change_file`, `input_code`, and `input_prompt` if provided). - Calls `change_main` with `ctx`, `use_csv`, `budget`, and relevant files. + - Parses gate block exit from result via `parse_prompt_gate_block_exit(result)` if result is a string, and if not None raises `click.exceptions.Exit(gate_exit)`. + - **`--evidence`**: When set, call `write_evidence_manifest` after successful run: + - In manual mode: with `command="pdd change"`, `prompt_file=input_prompt`, `output_files=[output] if output else ()`, `model=model`, `cost_usd=cost`, and `temperature`. + - In agentic mode: with `command="pdd change"`, `output_files=changed_files`, `model=model`, `cost_usd=cost`, `temperature`, and `basename="agentic-change"`. 4. **update**: - Doc: "Update the original prompt file based on code changes." - - Args: `files` (nargs=-1). Options: `--all` (param `all_`), `--extensions`, `--directory`, `--git`, `--output`, `--simple`, `--base-branch` (default `"main"`), `--budget` (float, default `None`), `--dry-run`, `--sync-metadata` (flag, default `False`). + - Args: `files` (nargs=-1). Options: `--all` (param `all_`), `--extensions`, `--directory`, `--git`, `--output`, `--simple`, `--base-branch` (default `"main"`), `--budget` (float, default `None`), `--dry-run`, `--json` (param as_json), `--sync-metadata` (flag, default `False`). - Decorators (in order): `@click.pass_context`, `@log_operation(operation="update", clears_run_report=True)`, `@track_cost`. - **Validation** (UsageError, raised before try/except so they propagate): - 2 args requires `--git`; 3 args forbids `--git`; max 3 args. - `--all` forbidden with file paths. - `--budget`, when set, must be > 0. - Repo mode (0 args or `--all`) forbids `--git` and `--output`. - - File modes forbid `--extensions`, `--directory`, non-default `--base-branch`, `--dry-run`, and `--budget`. + - File modes forbid `--extensions`, `--directory`, non-default `--base-branch`, `--dry-run`, `--json`, and `--budget`. + - In repo mode: `--json` is only supported with `--dry-run` (raises `click.UsageError("--json is only supported with update --all --dry-run.")` if `as_json` but not `dry_run`). + - In file modes: `--json` is forbidden (raises `click.UsageError("--json is only valid in repository-wide dry-run mode.")` if `as_json`). - **Modes**: - 0 args or `--all`: `repo=True`, all file params `None`. - 1 arg: `modified_code_file=files[0]` (regeneration). - 2 args: `input_prompt_file=files[0]`, `modified_code_file=files[1]` (git-based). - 3 args: `input_prompt_file=files[0]`, `modified_code_file=files[1]`, `input_code_file=files[2]`. + - **Repo Dry-Run JSON**: If repo mode, `dry_run`, and `as_json` are all True: call `build_report(consumer="update-dry-run")` from `..continuous_sync`, set `ctx.obj["_suppress_result_summary"] = True`, print the JSON report with `indent=2, sort_keys=True`, and return `None`. - **`--sync-metadata`** (opt-in): When set, `update_main` runs the shared `run_metadata_sync` orchestrator after the prompt update — preserves or seeds prompt PDD tags from the architecture entry, reconciles the architecture.json entry, clears stale run reports, and finalizes the fingerprint last. Compatible with all modes (single-file, regeneration, repo). `failed` in any stage causes the command to exit non-zero (raises `click.exceptions.Exit(1)`); `skipped` is acceptable and passes through (no `architecture.json`, unregistered modules, LLM-first tag refresh pending #870 — not implemented here). Help text: "After update, run the shared metadata-sync orchestrator (preserve/seed PDD tags, reconcile architecture.json entry, clear stale run reports, finalize fingerprint last). On any stage failed, exits non-zero. Stages may report skipped for legitimate cases (no architecture.json, unregistered modules). LLM-first refresh of stale-but-present tags is tracked at #870 and is NOT invoked here." - Calls `update_main(ctx, input_prompt_file, modified_code_file, input_code_file, output, use_git=git, repo, extensions, directory, simple, base_branch, budget, dry_run, sync_metadata=sync_metadata)` and returns its result (or `None` if it returns `None`). From 20f962f7f043b91bbc2e4ad36a1dfe6f649af862 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:28:46 -0700 Subject: [PATCH 18/30] Surface pending CONFLICT in `pdd sync --dry-run` (#1929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A dry-run previously only replayed the operation log, so a freshly-created CONFLICT (prompt AND a derived artifact both changed since the fingerprint) was invisible until a real sync ran. The dry-run branch now computes the current decision read-only (log_mode=True, read_only=True — no lock, no fingerprint/metadata mutation) via a new _display_dry_run_decision helper and prints a 'Current analysis:' line, prefixing a CONFLICT with its actionable resolution message. test_dry_run_mode updated deliberately: dry-run now makes exactly one read-only sync_determine_operation call (asserted read_only/log_mode). Adds test_dry_run_surfaces_conflict_without_side_effects (real path, fingerprint byte-identical after) and test_conflict_reason_surfaces_actionable_resolve_command (the reason with 'pdd resolve' reaches result['errors']). Prompt + meta realigned for the new dry-run behavior; both gates green. Co-Authored-By: Claude --- .pdd/meta/sync_orchestration_python.json | 10 +-- pdd/prompts/sync_orchestration_python.prompt | 3 +- pdd/sync_orchestration.py | 57 +++++++++++++ tests/test_sync_orchestration.py | 85 +++++++++++++++++++- 4 files changed, 147 insertions(+), 8 deletions(-) diff --git a/.pdd/meta/sync_orchestration_python.json b/.pdd/meta/sync_orchestration_python.json index 928efe35bf..49e8f50c07 100644 --- a/.pdd/meta/sync_orchestration_python.json +++ b/.pdd/meta/sync_orchestration_python.json @@ -1,13 +1,13 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.476722+00:00", + "timestamp": "2026-07-09T20:27:44.302455+00:00", "command": "fix", - "prompt_hash": "31fceea8fcb2e3933a156779918cce48ae3a108541b1a0d5203652cac919a22b", - "code_hash": "66b8002c0123618f6030600e5a68f74eef6c2731ef51e7b9c753f068c55dbe5d", + "prompt_hash": "7057abe1c3aba316609caca0e541cba0fedf923ccdb72d43cb2b76a5f66cb4e9", + "code_hash": "c6f33c49e349aa9db28946c7c2d5c94d8617e3ec2432ed00e27a9174660897be", "example_hash": "cc1313a948946026d418c85a07e5bf0eedeb5915c44d630440e489979755e1f7", - "test_hash": "7a4a23ed7c00408887d4ca9b604cb9715e0ad6e0a9c3e9e1b4df78603b396f41", + "test_hash": "33396877e08938d51f40bb2622a68676e4013801235f334a54384ca583b5791f", "test_files": { - "test_sync_orchestration.py": "7a4a23ed7c00408887d4ca9b604cb9715e0ad6e0a9c3e9e1b4df78603b396f41" + "test_sync_orchestration.py": "33396877e08938d51f40bb2622a68676e4013801235f334a54384ca583b5791f" }, "include_deps": { "docs/whitepaper.md": "3347db03fa35376024b59d8546efdf0858655746490561b88b710fa6b85017cc", diff --git a/pdd/prompts/sync_orchestration_python.prompt b/pdd/prompts/sync_orchestration_python.prompt index 638faa76ad..b143903dd0 100644 --- a/pdd/prompts/sync_orchestration_python.prompt +++ b/pdd/prompts/sync_orchestration_python.prompt @@ -253,7 +253,7 @@ For every call to `sync_determine_operation`, compute `isolated_replay_or_repair ### Dry-Run Mode -When `dry_run=True`, display the sync log at `.pdd/meta/{basename}_{language.lower()}_sync.log` (JSONL format) and return immediately. Normal mode shows concise output; verbose mode shows full details including decision type, confidence, and budget info. +When `dry_run=True`, first surface the CURRENT decision via `_display_dry_run_decision(...)` — it calls `sync_determine_operation(..., log_mode=True, read_only=True)` (no lock, no fingerprint/metadata mutation) and prints a `Current analysis:` line, prefixing a pending `CONFLICT` (prompt+derived both changed) with its actionable resolution message (#1929) so a never-synced conflict is visible before any log entry exists. Then display the sync log at `.pdd/meta/{basename}_{language.lower()}_sync.log` (JSONL format) and return immediately. Normal mode shows concise output; verbose mode shows full details including decision type, confidence, and budget info. Dry-run must not write snapshot artifacts. If nondeterministic context can be detected without executing dynamic tags, report that a snapshot would be required, but do not execute shell/web/query tags solely for dry-run detection. @@ -389,6 +389,7 @@ entry = create_log_entry( ### Local helpers (implement in this module) +- `_display_dry_run_decision(basename, language, target_coverage, prompts_dir, skip_tests, skip_verify, context_override, quiet)` - Read-only helper (#1929) that computes the current `sync_determine_operation(..., log_mode=True, read_only=True)` decision and prints a `Current analysis:` line for `--dry-run`, prefixing a `CONFLICT` classification with its actionable reason. Best-effort: swallow any analysis error and return `None` so the log replay still runs; suppress output when `quiet`. - `_display_sync_log(basename, language, verbose, paths=None)` - Format and display sync log using `load_operation_log()`; pass `paths=pdd_files` for subproject anchoring (issue #1211). Suppress the `Model:` header if the model name is empty, "unknown", or "N/A" (case-insensitive). - `_create_mock_context(**kwargs)` - Create Click context for command execution - `_parse_test_output(output, language)` - Parse test runner output to extract (tests_passed, tests_failed, coverage) diff --git a/pdd/sync_orchestration.py b/pdd/sync_orchestration.py index 4e7e70c145..db9bc725c3 100644 --- a/pdd/sync_orchestration.py +++ b/pdd/sync_orchestration.py @@ -1889,6 +1889,50 @@ def _create_mock_context(**kwargs) -> click.Context: return ctx +def _display_dry_run_decision( + basename: str, + language: str, + target_coverage: float, + prompts_dir: str, + skip_tests: bool, + skip_verify: bool, + context_override: Optional[str], + quiet: bool, +) -> Optional[SyncDecision]: + """Print the current read-only sync decision for a ``--dry-run`` (#1929). + + A dry-run otherwise only replays the operation log, so a freshly-created + CONFLICT (prompt AND a derived artifact both changed since the fingerprint) + is invisible until a real sync runs. This computes the current decision in + ``read_only``/``log_mode`` — no lock, no fingerprint or metadata mutation — + and surfaces it, giving a pending CONFLICT its actionable resolution message + without any side effects. Best-effort: any analysis error is swallowed so the + log replay below still runs. + """ + try: + decision = sync_determine_operation( + basename, + language, + target_coverage, + prompts_dir=prompts_dir, + skip_tests=skip_tests, + skip_verify=skip_verify, + context_override=context_override, + log_mode=True, + read_only=True, + ) + except Exception: # pylint: disable=broad-except + return None + if decision is None or quiet: + return decision + classification = (decision.details or {}).get('classification') + if classification == 'CONFLICT': + print(f"Current analysis: CONFLICT — {decision.reason}") + else: + print(f"Current analysis: {decision.operation} — {decision.reason}") + return decision + + def _display_sync_log( basename: str, language: str, @@ -2046,6 +2090,19 @@ def sync_orchestration( raise except Exception: _dry_paths = None + # #1929: surface the CURRENT decision (especially a pending CONFLICT) so a + # dry-run reports what sync WOULD do, not just past log entries. Read-only: + # no lock, fingerprint, or metadata mutation. + _display_dry_run_decision( + basename, + language, + target_coverage, + prompts_dir, + skip_tests, + skip_verify, + context_override, + quiet, + ) if _dry_paths: return _display_sync_log(basename, language, verbose, paths=_dry_paths) return _display_sync_log(basename, language, verbose) diff --git a/tests/test_sync_orchestration.py b/tests/test_sync_orchestration.py index 16d9c86644..0ad7193758 100644 --- a/tests/test_sync_orchestration.py +++ b/tests/test_sync_orchestration.py @@ -1394,9 +1394,63 @@ def test_dry_run_mode(orchestration_fixture): assert not extra_kwargs, f"unexpected extra kwargs: {extra_kwargs!r}" assert result == mock_log_display.return_value - # Ensure main workflow components were not touched + # Ensure the main workflow (locking, execution) was not touched. orchestration_fixture['SyncLock'].assert_not_called() - orchestration_fixture['sync_determine_operation'].assert_not_called() + # #1929: dry-run now also computes the CURRENT decision read-only so a pending + # CONFLICT surfaces (see test_dry_run_surfaces_conflict). This is analysis + # only — read_only=True / log_mode=True — so no metadata is mutated. + determine_calls = orchestration_fixture['sync_determine_operation'].call_args_list + assert len(determine_calls) == 1 + assert determine_calls[0].kwargs.get('read_only') is True + assert determine_calls[0].kwargs.get('log_mode') is True + +def test_dry_run_surfaces_conflict_without_side_effects(tmp_path, monkeypatch, capsys): + """#1929: `pdd sync --dry-run` reports a pending CONFLICT and mutates nothing. + + Runs the real (unmocked) dry-run path over an on-disk unit whose prompt AND + code both changed since the fingerprint. The current-analysis line must name + the CONFLICT and the `pdd resolve` command, and the fingerprint must be byte + identical afterwards. + """ + from datetime import datetime, timezone + from pdd.sync_determine_operation import calculate_sha256 + + monkeypatch.chdir(tmp_path) + (tmp_path / ".pdd" / "meta").mkdir(parents=True, exist_ok=True) + (tmp_path / "prompts").mkdir(exist_ok=True) + + def _w(path, content): + path = Path(path) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content, encoding="utf-8") + return calculate_sha256(path) + + prompt_hash = _w(tmp_path / "prompts" / "widget_python.prompt", "Generate a simple function.\n") + paths = get_pdd_file_paths("widget", "python", prompts_dir="prompts") + code_hash = _w(Path(paths["code"]), "def value():\n return 1\n") + example_hash = _w(Path(paths["example"]), "print(1)\n") + test_hash = _w(Path(paths["test"]), "def test_v():\n assert True\n") + fp_path = tmp_path / ".pdd" / "meta" / "widget_python.json" + fp_path.write_text(json.dumps({ + "pdd_version": "t", "timestamp": datetime.now(timezone.utc).isoformat(), + "command": "fix", "prompt_hash": prompt_hash, "code_hash": code_hash, + "example_hash": example_hash, "test_hash": test_hash, + "test_files": {Path(paths["test"]).name: test_hash}, "include_deps": {}, + }), encoding="utf-8") + # Co-edit prompt + code -> both-changed CONFLICT. + _w(tmp_path / "prompts" / "widget_python.prompt", "Generate a CHANGED function.\n") + _w(Path(paths["code"]), "def value():\n return 2\n") + fp_before = fp_path.read_text(encoding="utf-8") + + result = sync_orchestration(basename="widget", language="python", dry_run=True) + + out = capsys.readouterr().out + assert "CONFLICT" in out + assert "pdd resolve widget --accept-current" in out + # Strictly read-only: the fingerprint is untouched. + assert fp_path.read_text(encoding="utf-8") == fp_before + assert result is not None + def test_skip_verify_flag(orchestration_fixture): """ @@ -1457,6 +1511,33 @@ def test_manual_merge_request(orchestration_fixture): assert 'Manual merge required' in result['errors'][0] assert not result['operations_completed'] + +def test_conflict_reason_surfaces_actionable_resolve_command(orchestration_fixture): + """#1929: the actionable CONFLICT reason reaches the user's error summary. + + Orchestration must not swallow a CONFLICT into a silent success: it surfaces + the decision reason verbatim, including the exact `pdd resolve` command, so a + non-interactive/CI run reports how to resolve rather than healing the unit. + """ + mock_determine = orchestration_fixture['sync_determine_operation'] + mock_determine.return_value = SyncDecision( + operation='fail_and_request_manual_merge', + reason=( + "CONFLICT: 'calculator' — prompt and code changed since the last sync, " + "so pdd will not auto-pick a winner (that would discard your edits). " + "Resolve with `pdd resolve calculator --accept-current` (keep the current " + "files as the new baseline)." + ), + details={'classification': 'CONFLICT'}, + ) + + result = sync_orchestration(basename="calculator", language="python") + + assert result['success'] is False + assert not result['operations_completed'] + assert 'pdd resolve calculator --accept-current' in result['errors'][0] + + def test_unexpected_exception_handling(orchestration_fixture): """ Ensures the finally block runs and cleans up even with unexpected errors. From e198a1b5b727c4a289ed1a08a03c789806464892 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:28:46 -0700 Subject: [PATCH 19/30] Tests: CONFLICT actionable message + pdd resolve command (#1929) test_sync_determine_operation.py: assert the CONFLICT reason names the unit, what moved, and the exact pdd resolve commands, and that details carries basename/language/resolution_commands; a helper test covers the --language suffix and 3-way co-edit phrasing. (Unit test_hash re-stamped since these tests live in the unit's tracked test file.) test_resolve_command.py (new): pdd resolve --accept-current turns a CONFLICT IN_SYNC and stamps the CHANGED code (not the old baseline), preserving the fingerprint; --json reports before/after; --prompt-wins/--code-wins are documented stubs that exit non-zero and do not mutate the fingerprint; exactly-one-strategy and unknown-unit guards. Co-Authored-By: Claude --- .../meta/sync_determine_operation_python.json | 6 +- tests/test_resolve_command.py | 202 ++++++++++++++++++ tests/test_sync_determine_operation.py | 50 +++++ 3 files changed, 255 insertions(+), 3 deletions(-) create mode 100644 tests/test_resolve_command.py diff --git a/.pdd/meta/sync_determine_operation_python.json b/.pdd/meta/sync_determine_operation_python.json index 3871862378..45b67ef874 100644 --- a/.pdd/meta/sync_determine_operation_python.json +++ b/.pdd/meta/sync_determine_operation_python.json @@ -1,13 +1,13 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:13:33.585502+00:00", + "timestamp": "2026-07-09T20:27:44.291703+00:00", "command": "fix", "prompt_hash": "d09025959647edcc9076cb860723b3c563ab08415a021656dc2274421c576759", "code_hash": "764fc1f22c682fd6bb146731060a20f33a2c1caf921079abcda385a7be443a81", "example_hash": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5", - "test_hash": "0e896d21fdf4a2974a3fc0ae3332308e2f2d3d30f4fdb13d39b075c3fb8ec04d", + "test_hash": "214be5ec2ee7563ce922ba7a3a9a860ee5b4a24c1c98cca946ce7664fa24343d", "test_files": { - "test_sync_determine_operation.py": "0e896d21fdf4a2974a3fc0ae3332308e2f2d3d30f4fdb13d39b075c3fb8ec04d" + "test_sync_determine_operation.py": "214be5ec2ee7563ce922ba7a3a9a860ee5b4a24c1c98cca946ce7664fa24343d" }, "include_deps": { "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", diff --git a/tests/test_resolve_command.py b/tests/test_resolve_command.py new file mode 100644 index 0000000000..d65d67e9df --- /dev/null +++ b/tests/test_resolve_command.py @@ -0,0 +1,202 @@ +"""Tests for the ``pdd resolve`` command (#1929). + +``pdd resolve`` finalizes a both-changed CONFLICT unit: +* ``--accept-current`` deterministically stamps the current tree as the baseline; +* ``--prompt-wins`` / ``--code-wins`` preview the not-yet-automated LLM strategies. + +The setup builds a real on-disk unit with a committed fingerprint, then co-edits +the prompt and the code so the unit classifies as CONFLICT — the exact state the +command exists to resolve. +""" +from __future__ import annotations + +import json +import os +from datetime import datetime, timezone +from pathlib import Path +from typing import Tuple + +from click.testing import CliRunner + +from pdd import continuous_sync as cs +from pdd.commands.resolve import resolve +from pdd.sync_determine_operation import ( + calculate_sha256, + get_pdd_file_paths, + read_fingerprint, +) + +BASENAME = "widget" +LANGUAGE = "python" + + +def _write(path: Path, content: str) -> str: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content, encoding="utf-8") + return calculate_sha256(path) + + +def _make_conflict_unit(base: Path) -> Tuple[str, str, Path]: + """Create a synced unit then co-edit prompt + code so it becomes CONFLICT.""" + os.chdir(base) + (base / ".pdd" / "meta").mkdir(parents=True, exist_ok=True) + (base / "prompts").mkdir(exist_ok=True) + + prompt_hash = _write( + base / "prompts" / f"{BASENAME}_{LANGUAGE}.prompt", + "Generate a simple function.\n", + ) + paths = get_pdd_file_paths(BASENAME, LANGUAGE, prompts_dir="prompts") + code_hash = _write(Path(paths["code"]), "def value():\n return 1\n") + example_hash = _write(Path(paths["example"]), "print(1)\n") + test_hash = _write(Path(paths["test"]), "def test_v():\n assert True\n") + + fp_path = base / ".pdd" / "meta" / f"{BASENAME}_{LANGUAGE}.json" + fp_path.write_text( + json.dumps( + { + "pdd_version": "test", + "timestamp": datetime.now(timezone.utc).isoformat(), + "command": "fix", + "prompt_hash": prompt_hash, + "code_hash": code_hash, + "example_hash": example_hash, + "test_hash": test_hash, + "test_files": {Path(paths["test"]).name: test_hash}, + "include_deps": {}, + } + ), + encoding="utf-8", + ) + + # Co-edit BOTH the prompt and the code -> both-changed CONFLICT. + _write( + base / "prompts" / f"{BASENAME}_{LANGUAGE}.prompt", + "Generate a CHANGED function.\n", + ) + _write(Path(paths["code"]), "def value():\n return 2\n") + return BASENAME, LANGUAGE, fp_path + + +def _classification(base: Path) -> str: + return cs.classify_unit(cs.discover_units(base, modules=[BASENAME])[0], base)[ + "classification" + ] + + +def test_accept_current_resolves_conflict_to_in_sync(): + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + base = Path(tmp) + _make_conflict_unit(base) + assert _classification(base) == "CONFLICT" + + result = runner.invoke(resolve, [BASENAME, "--accept-current"], obj={}) + + assert result.exit_code == 0, result.output + assert _classification(base) == "IN_SYNC" + assert "Resolved 'widget'" in result.output + + +def test_accept_current_stamps_the_current_tree_not_the_old_baseline(): + """The new baseline must fingerprint the CHANGED code (return 2), not the old.""" + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + base = Path(tmp) + _, _, fp_path = _make_conflict_unit(base) + paths = get_pdd_file_paths(BASENAME, LANGUAGE, prompts_dir="prompts") + current_code_hash = calculate_sha256(Path(paths["code"])) + + result = runner.invoke(resolve, [BASENAME, "--accept-current"], obj={}) + + assert result.exit_code == 0, result.output + # Fingerprint is preserved (never deleted) and now matches the current code. + assert fp_path.exists() + fingerprint = read_fingerprint(BASENAME, LANGUAGE, paths=paths) + assert fingerprint is not None + assert fingerprint.code_hash == current_code_hash + + +def test_accept_current_json_reports_before_and_after(): + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + base = Path(tmp) + _make_conflict_unit(base) + + result = runner.invoke( + resolve, [BASENAME, "--accept-current", "--json"], obj={} + ) + + assert result.exit_code == 0, result.output + payload = json.loads(result.output) + assert payload["resolved"] is True + assert payload["before"] == "CONFLICT" + assert payload["after"] == "IN_SYNC" + assert payload["strategy"] == "accept-current" + + +def test_prompt_wins_is_a_documented_stub_that_exits_nonzero(): + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + _make_conflict_unit(Path(tmp)) + + result = runner.invoke(resolve, [BASENAME, "--prompt-wins"], obj={}) + + assert result.exit_code == 2 + assert "not yet automated" in result.output + assert "pdd sync widget" in result.output + + +def test_code_wins_is_a_documented_stub_that_exits_nonzero(): + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + _make_conflict_unit(Path(tmp)) + + result = runner.invoke(resolve, [BASENAME, "--code-wins"], obj={}) + + assert result.exit_code == 2 + assert "not yet automated" in result.output + assert "pdd update widget" in result.output + + +def test_stub_previews_do_not_mutate_the_fingerprint(): + """A preview strategy must not change the on-disk baseline.""" + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + base = Path(tmp) + _, _, fp_path = _make_conflict_unit(base) + before = fp_path.read_text(encoding="utf-8") + + runner.invoke(resolve, [BASENAME, "--prompt-wins"], obj={}) + + assert fp_path.read_text(encoding="utf-8") == before + assert _classification(base) == "CONFLICT" + + +def test_requires_exactly_one_strategy(): + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + _make_conflict_unit(Path(tmp)) + + none_chosen = runner.invoke(resolve, [BASENAME], obj={}) + assert none_chosen.exit_code == 2 + assert "exactly one" in none_chosen.output + + two_chosen = runner.invoke( + resolve, [BASENAME, "--accept-current", "--prompt-wins"], obj={} + ) + assert two_chosen.exit_code == 2 + assert "exactly one" in two_chosen.output + + +def test_unknown_unit_errors_without_stamping(): + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + _make_conflict_unit(Path(tmp)) + + result = runner.invoke( + resolve, ["does_not_exist", "--accept-current"], obj={} + ) + + assert result.exit_code != 0 + assert "No PDD unit" in result.output diff --git a/tests/test_sync_determine_operation.py b/tests/test_sync_determine_operation.py index 58d243f102..0d1144f2e3 100644 --- a/tests/test_sync_determine_operation.py +++ b/tests/test_sync_determine_operation.py @@ -18,6 +18,7 @@ from sync_determine_operation import ( sync_determine_operation, analyze_conflict_with_llm, + _prompt_derived_conflict_decision, SyncLock, Fingerprint, RunReport, @@ -1123,6 +1124,55 @@ def test_prompt_code_coedit_conflict_with_real_paths_preserves_metadata(pdd_test assert paths["prompt"].read_text(encoding="utf-8") == "Generate a changed function.\n" +def test_conflict_message_is_actionable(pdd_test_environment): + """#1929: the CONFLICT reason names the unit, what moved, and the resolve commands.""" + paths = _write_complete_unit_with_fingerprint(pdd_test_environment) + paths["prompt"].write_text("Generate a changed function.\n", encoding="utf-8") + paths["code"].write_text("def value():\n return 2\n", encoding="utf-8") + + decision = sync_determine_operation( + BASENAME, + LANGUAGE, + TARGET_COVERAGE, + prompts_dir=str(pdd_test_environment / "prompts"), + ) + + assert decision.operation == "fail_and_request_manual_merge" + assert decision.details["classification"] == "CONFLICT" + # The reason is self-actionable: names the unit, what moved, the exact commands. + assert BASENAME in decision.reason + assert "prompt" in decision.reason and "code" in decision.reason + assert f"pdd resolve {BASENAME} --accept-current" in decision.reason + assert f"pdd resolve {BASENAME} --prompt-wins" in decision.reason + assert f"pdd resolve {BASENAME} --code-wins" in decision.reason + # Structured details for machine consumers (CI summaries, drift ledger). + assert decision.details["basename"] == BASENAME + assert decision.details["language"] == LANGUAGE + commands = decision.details["resolution_commands"] + assert commands["accept_current"] == f"pdd resolve {BASENAME} --accept-current" + assert commands["prompt_wins"] == f"pdd resolve {BASENAME} --prompt-wins" + assert commands["code_wins"] == f"pdd resolve {BASENAME} --code-wins" + + +def test_conflict_decision_helper_formats_language_suffix_and_artifacts(): + """Non-Python units get a --language suffix; 3-way co-edits read naturally.""" + decision = _prompt_derived_conflict_decision( + basename="parser", + language="javascript", + changes=["prompt", "code", "test"], + paths={}, + fingerprint=None, + read_only=True, + ) + commands = decision.details["resolution_commands"] + assert commands["accept_current"] == "pdd resolve parser --language javascript --accept-current" + assert commands["code_wins"] == "pdd resolve parser --language javascript --code-wins" + assert "prompt, code, and test changed" in decision.reason + assert decision.details["read_only"] is True + # Non-destructive contract holds regardless of language. + assert decision.operation == "fail_and_request_manual_merge" + + # --- Part 3: `analyze_conflict_with_llm` --- @patch('sync_determine_operation.get_git_diff', return_value="fake diff") From 0574cf28081a4be90755754a70aae3b6f521ce5b Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:31:42 -0700 Subject: [PATCH 20/30] Prompt catch-up: back-propagate agentic_test_generate (A2 pilot 3) pdd update (agentic, provider=google) back-propagated code->prompt for the code-ahead unit agentic_test_generate (queue rank 32, non-conflict, code 36d ahead -- the most-stale non-conflict unit). Public entry run_agentic_test_generate retained. Code untouched; tests/test_agentic_test_generate.py 44 passed. Re-stamped: pdd update's meta write NULLED example_hash/test_hash/test_files (it maintains only prompt_hash/code_hash), which fails --check; the stamper restores the full fingerprint. --check clean. Co-Authored-By: Claude --- .pdd/meta/agentic_test_generate_python.json | 6 +- .../agentic_test_generate_python.prompt | 83 +++++++++---------- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/.pdd/meta/agentic_test_generate_python.json b/.pdd/meta/agentic_test_generate_python.json index bca10c01ba..fc162bcc53 100644 --- a/.pdd/meta/agentic_test_generate_python.json +++ b/.pdd/meta/agentic_test_generate_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.286814+00:00", - "command": "fix", - "prompt_hash": "028c512165adf77ee126b1d10be74c53df990fbf4206b919b42cfae966d4d13f", + "timestamp": "2026-07-09T20:31:24.776846+00:00", + "command": "update", + "prompt_hash": "6d77ecd278bedaf7504434656e855bcb25accb0fb843d901ed3be899ad2c158e", "code_hash": "5c34b242014d6cc56a1e9504bc649032ecea24fc09c50754afad2d421053020e", "example_hash": "5b021f33624a41accf5463ea151ccfaab9f9f268ca95fb21c94e3f0dda9f4661", "test_hash": "29a887349d31f0a1233ae1375be56dd4530bf8d9d1ca8c38917091f105fc1024", diff --git a/pdd/prompts/agentic_test_generate_python.prompt b/pdd/prompts/agentic_test_generate_python.prompt index be58850bc7..66f23e0690 100644 --- a/pdd/prompts/agentic_test_generate_python.prompt +++ b/pdd/prompts/agentic_test_generate_python.prompt @@ -4,61 +4,52 @@ Write the pdd/agentic_test_generate.py module. % Role & Scope -Agentic test generation for non-Python languages. Instead of using a single LLM -call (which often produces incorrect test file extensions or doesn't follow the -correct framework), this module delegates to an agentic CLI that can: -1. Explore the project structure -2. Discover test frameworks (Jest, JUnit, Go test, Cargo test, etc.) -3. Generate tests -4. Run them to verify they pass +Provides agentic test generation for non-Python languages. Instead of a single LLM call, this module delegates to an agentic CLI to explore the project, discover test frameworks, generate tests, and run them. % Entry Point -`run_agentic_test_generate(prompt_file, code_file, output_test_file, *, verbose: bool = False, quiet: bool = False, repair_directive: str | None = None)` +`run_agentic_test_generate(prompt_file: Path, code_file: Path, output_test_file: Path, *, verbose: bool = False, quiet: bool = False, repair_directive: str | None = None) -> TestResult` -Returns: `tuple[str, float, str, bool, str]` → `(generated_content, cost, model_name, success, error_message)` -- generated_content: The content of the generated test file -- cost: Estimated LLM cost -- model_name: Model/provider used (formatted as "agentic-{provider}") -- success: Whether the agentic test generation succeeded (tests passed) -- error_message: Empty string on success; on failure, the error/message from run_agentic_task +Returns: `TestResult` (imported from `.test_result` containing `content`, `cost`, `model`, `agentic_success`, and `error_message`). +- `content`: Generated test file content (empty string if none) +- `cost`: Estimated LLM cost +- `model`: Formatted as `"agentic-{provider}"` or `"agentic-cli"` (fallback) +- `agentic_success`: True if tests passed, False if failed, None if early error +- `error_message`: Empty string on success, else the error/failure message % LLM Prompt Template -Uses `agentic_test_generate_LLM` (loaded via load_prompt_template). - -Template placeholders: -- `{prompt_path}`: Absolute path to prompt file -- `{code_path}`: Absolute path to code file -- `{test_path}`: Absolute path to output test file -- `{project_root}`: Absolute path to project root -- `{prompt_content}`: Content of prompt file -- `{code_content}`: Content of code file +Uses template `agentic_test_generate_LLM` (loaded via `load_prompt_template`). +Template placeholders to format: +- `prompt_path`: Absolute path to prompt file +- `code_path`: Absolute path to code file +- `test_path`: Absolute path to output test file +- `project_root`: Absolute path to project root +- `prompt_content`: Content of prompt file (augmented with repair_directive if present) +- `code_content`: Content of code file % Requirements -1. Single-pass agentic execution (no retry loops) -2. Record file mtimes before agent runs, detect changes after -3. Agent writes the test file directly; module reads it back for return value -4. If expected output file doesn't exist, check changed_files for any new test/spec files. When the agent wrote to such an alternate path (e.g. `__tests__/foo.test.ts` instead of the canonical `output_test_file`), the OUTER churn check in `cmd_test_main` compares the alt-path's NEW content against the CANONICAL path's pre-existing content (empty when canonical didn't exist), letting a 20-test alt file shrink to 1 without tripping `TestChurnError`. To close that gap, BEFORE running the agent take a working-tree content snapshot of every existing file matching `_is_test_output_path` under `project_root` via `_snapshot_pre_test_contents(project_root, mtimes_before.keys()) -> dict[Path, str]`; this captures tracked-clean, tracked-dirty, AND untracked files alike (so neither an untracked alt-path test nor uncommitted local edits get treated as first-time generation, and a restore-on-failure never silently discards dirty work). Bound per-file at ~1 MiB to keep snapshot memory predictable; files above the cap fall through to first-time-generation behavior. Lazy-import `_is_test_output_path` from `code_generator_main` to avoid a circular dependency. AFTER the agent runs, when the alt-path fallback fires, look up the alt path's prior content from this snapshot (NOT from `git show HEAD:` — that would miss untracked alt files entirely and on restore would clobber the user's local dirty edits with HEAD) and call `_verify_test_churn(existing_code=prior, generated_code=alt_content, prompt_name=prompt_file.name, output_path=str(alt_path), prompt_content=prompt_content)`. On `TestChurnError`: set `total_cost`/`model_name` on the exception, RESTORE the alt path's snapshotted pre-run content to disk (so the repair loop sees the actual pre-sync working-tree state), then re-raise. Lazy-import `_verify_test_churn`/`TestChurnError` from `code_generator_main`. -5. Parse JSON from agent output to get success/message metadata -6. Return empty string for content if no test file was generated -7. **Repair-directive injection via explicit kwarg** (#1012, F-A / F-H): `run_agentic_test_generate` accepts a `repair_directive: str | None = None` keyword-only parameter. After reading `prompt_content` from the prompt file on disk and BEFORE passing it into the agent instruction template format, if `repair_directive` is non-empty (after stripping) append a `...` block to `prompt_content` containing the stripped directive. This mirrors the `` injection in `code_generator_main` and the native-path injection in `cmd_test_main`, so test-op retries from `sync_orchestration._run_test_op_with_churn_retry` actually see a different prompt on the second attempt. **`run_agentic_test_generate` MUST NOT read `PDD_REPAIR_DIRECTIVE` from `os.environ`**: a stale outer value would otherwise contaminate direct invocations that have no active retry context. The retry helpers source the directive from their loop-local state and pass it explicitly through `cmd_test_main(..., repair_directive=...)` which forwards it here. Do NOT mutate the on-disk prompt file — only the in-process `prompt_content` flowing into `template.format(...)` is augmented. +1. **Agent and Template Loading**: Check available agents via `get_available_agents()`. If empty, return `TestResult` with `success=False` and a clear error message. Load the prompt template; if it fails, return `TestResult` with `success=False` and error. +2. **Repair Directive Injection**: Accepts a `repair_directive` kwarg. If non-empty, append it to `prompt_content` wrapped in a `` block before formatting. Do NOT read `PDD_REPAIR_DIRECTIVE` from the environment or mutate the on-disk file. +3. **Mtime Recording**: Before running the agent, record file mtimes across the project root using `_get_file_mtimes(root: Path)`. Ignore `.git`, `__pycache__`, `.venv`, `venv`, `node_modules`, `.idea`, `.vscode`, `.pdd`. +4. **Pre-test Snapshotted Contents**: Before the run, snapshot the contents of existing test-like files under `project_root` via `_snapshot_pre_test_contents` (for files in candidate paths matching `_is_test_output_path` and sized <= 1 MiB). Lazy-import `_is_test_output_path` from `code_generator_main` to avoid a circular dependency. +5. **Agent Task Execution**: Execute the task via `run_agentic_task(instruction=instruction, cwd=project_root, verbose=verbose, quiet=quiet, label="test-generate", timeout=AGENTIC_STEP_TIMEOUT_SECONDS, max_retries=DEFAULT_MAX_RETRIES)`. +6. **Output Parsing**: + - Detect changed files using mtimes comparison. + - Read the canonical test file via `_read_generated_test_file`. + - Parse JSON metadata from agent output using `_extract_json_from_text` (handles raw JSON and markdown blocks). If missing JSON but agent succeeded and generated a test file, infer success and set a default message. +7. **Test Churn Sweep**: + - Skip sweep if env flags (`PDD_SKIP_TEST_CHURN_GATE`, `PDD_SKIP_CONFORMANCE`) are enabled or if the prompt allows churn. + - Otherwise, iterate through all pre-run snapshotted files: + - **Deletion**: If a snapshotted file was deleted, treat as maximal churn (`churn_ratio=1.0`), restore all snapshotted files from pre-test contents, and raise `TestChurnError` with cost, model, and a specific repair directive. + - **Rewrite**: If a snapshotted file was changed, verify churn using `_verify_test_churn(existing_code, generated_code, prompt_name, output_path, prompt_content)`. On `TestChurnError`, set its cost/model, restore all snapshotted files, and raise/re-raise. + - Lazy-import `_verify_test_churn`, `TestChurnError`, `_get_test_churn_threshold`, `_prompt_allows_test_churn`, and `_env_flag_enabled` from `code_generator_main`. +8. **Alternative Path Fallback**: If the expected canonical test file doesn't exist but changed files contain test/spec files, read the first match as the generated content. % Helper Functions - -### `_get_file_mtimes(root: Path) -> dict[Path, float]` -Recursively scan directory to record file modification times. -Ignores: .git, __pycache__, .venv, venv, node_modules, .idea, .vscode, .pdd - -### `_extract_json_from_text(text: str) -> dict[str, Any] | None` -Extract JSON object from text (handles markdown code blocks and raw JSON). - -### `_read_generated_test_file(test_file: Path) -> str` -Read the generated test file content if it exists, empty string otherwise. - -### `_snapshot_pre_test_contents(project_root: Path, candidate_paths: Iterable[Path]) -> dict[Path, str]` -Read the on-disk content of every file in `candidate_paths` that lives under `project_root` and matches `_is_test_output_path`. Skips files >1 MiB and silently drops paths that fail `OSError`. Used to capture the alt-path churn baseline BEFORE the agent runs, so tracked-clean / tracked-dirty / untracked test files are all covered uniformly. The dict's later `.get(alt_path, "")` lookup and restore-on-failure step give the repair loop the real pre-sync working-tree content instead of HEAD. - -### `_detect_changed_files(before, after, project_root) -> list[str]` -Detect which files changed between two mtime snapshots (new, modified, deleted). +- `_get_file_mtimes(root: Path) -> dict[Path, float]`: Scans root recursively and returns modification times, ignoring hidden/venv/node_modules directories. +- `_extract_json_from_text(text: str) -> dict[str, Any] | None`: Extracts and decodes JSON from text or markdown blocks. +- `_snapshot_pre_test_contents(project_root: Path, candidate_paths: Iterable[Path]) -> dict[Path, str]`: Reads and returns the content of candidate files under project_root matching `_is_test_output_path` and under 1 MiB. +- `_read_generated_test_file(test_file: Path) -> str`: Reads and returns the test file content, or empty string on error/nonexistence. +- `_detect_changed_files(before: dict[Path, float], after: dict[Path, float], project_root: Path) -> list[str]`: Compares pre- and post-run snapshots to return relative paths of added, modified, or deleted files. % Dependencies From 89f1b5d517a56317ca8b95d3f014abed13e576ee Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:32:19 -0700 Subject: [PATCH 21/30] Rebuild continuous_sync on stamper resolution + real hashes (part of #1927) Replace continuous_sync's discover_units/get_pdd_file_paths path logic with the Wave-0 stamper's resolution (pdd/prompts rglob + architecture.json filepath overrides + slash-basenames, each unit -> its own .pdd/meta), while keeping pdd's real hash functions (calculate_current_hashes / save_fingerprint) so a reconcile stamp is byte-identical to `pdd sync`. This is the single implementation issue #1927 asks for; scripts/stamp_fingerprints.py becomes a thin wrapper over it in a follow-up commit. Fixes both classification false positives on the clean tree (the same tree the CI stamper reports as fully current): - commands/firecrawl: was FAILURE "incomplete metadata: test_hash" because the underscore meta-derived basename resolved the test to the stray flat tests/test_commands_firecrawl.py. Correct resolution -> IN_SYNC. - core/remote_session vs remote_session: was DOC_CHANGED because both collapsed to one safe-basename and cross-wired fingerprints. Each now maps to its own meta -> IN_SYNC. Stamping is idempotent: a unit whose content hashes already match its stored fingerprint is not rewritten (timestamp preserved, zero writes), so a repo-wide restamp touches only genuinely-changed units (pdd_cloud restamp-churn addendum). Machine-readable verdicts gain the issue #884 shape (status / reasons / affected_artifacts / remediation) alongside the existing classification fields. CONFLICT keeps its definition (prompt-side AND code/derived-side both moved) to stay aligned with the sync decision path (#1929). build_report's public signature/report shape is preserved for existing callers (ci_drift_heal, maintenance, modify dry-runs); adds accept_current/backfill. Co-Authored-By: Claude --- pdd/continuous_sync.py | 1273 +++++++++++++++++++++++----------------- 1 file changed, 749 insertions(+), 524 deletions(-) diff --git a/pdd/continuous_sync.py b/pdd/continuous_sync.py index a1ae64baeb..2bcb69168c 100644 --- a/pdd/continuous_sync.py +++ b/pdd/continuous_sync.py @@ -1,29 +1,87 @@ -"""Deterministic continuous-sync classification and reconciliation reports.""" +"""Deterministic continuous-sync classification and reconciliation (shared core). + +This is the single implementation behind two surfaces: + +* ``pdd reconcile`` (``pdd/commands/reconcile.py``) — classify drift and, for the + safe cases, stamp ``.pdd/meta`` fingerprints to the current tree. +* ``scripts/stamp_fingerprints.py`` — the CI stamper/verifier, now a thin wrapper + over this module (issue #1927: no second hashing implementation). + +Unit/path resolution follows the repo's prompt tree and ``architecture.json``: +every ``pdd/prompts/[sub/]_python.prompt`` is one unit whose basename keeps +its subdirectory (``commands/firecrawl``, not the flattened ``commands_firecrawl``), +and whose code path honours an ``architecture.json`` ``filepath`` override, else the +``pdd/.py`` convention. Each unit maps to its own +``.pdd/meta/_python.json`` fingerprint. Hashing uses pdd's real +functions (``sync_determine_operation.calculate_current_hashes`` / +``operation_log.save_fingerprint``) so a reconcile stamp is byte-identical to what +``pdd sync`` would write. Zero LLM calls, no code/test regeneration. + +Classification vocabulary (unchanged from #1954, the CONFLICT definition is shared +with the sync decision path in ``sync_determine_operation``): a unit is IN_SYNC, +one of the single-sided drift states (DOC/PROMPT/CODE/TEST/EXAMPLE/DERIVED_CHANGED), +CONFLICT (prompt-side *and* code/derived-side both moved vs the stored meta), +UNBASELINED (missing / structurally invalid fingerprint) or FAILURE (resolution +error). Machine-readable verdicts additionally carry the issue #884 shape +(``status`` / ``reasons`` / ``affected_artifacts`` / ``remediation``). +""" from __future__ import annotations +import contextlib +import fnmatch +import glob import json +import os import subprocess -from dataclasses import dataclass +from dataclasses import dataclass, field from datetime import datetime, timezone -from itertools import combinations from pathlib import Path -from typing import Any, Dict, Iterable, List, Optional +from typing import Any, Dict, Iterable, List, Optional, Tuple -from .operation_log import ( - _safe_basename, - get_fingerprint_path, - infer_module_identity, - save_fingerprint, -) +from .operation_log import _safe_basename, save_fingerprint from .sync_determine_operation import ( Fingerprint, calculate_current_hashes, - calculate_sha256, - get_pdd_file_paths, read_fingerprint, ) +# --- Constants --------------------------------------------------------------- + +LANGUAGE = "python" +PROMPT_SUFFIX = f"_{LANGUAGE}.prompt" + +# Hash fields compared to decide currency (metadata fields pdd_version / +# timestamp / command are not content-derived and are never compared). +HASH_FIELDS: Tuple[str, ...] = ( + "prompt_hash", + "code_hash", + "example_hash", + "test_hash", + "test_files", + "include_deps", +) + +# Fingerprint dataclass field order (mirrors sync_determine_operation.Fingerprint / +# operation_log.save_fingerprint's asdict(...) json.dump order). Re-exported for the +# stamper wrapper's byte-format test. +FIELD_ORDER: Tuple[str, ...] = ( + "pdd_version", + "timestamp", + "command", + "prompt_hash", + "code_hash", + "example_hash", + "test_hash", + "test_files", + "include_deps", +) + +# ``command`` recorded when a unit is stamped for the first time (backfill). 'fix' +# satisfies sync's completion gates and triggers none of its special branches; it +# is the modal command among committed fingerprints. +NEW_UNIT_COMMAND = "fix" +IN_SYNC_CLASSIFICATION = "IN_SYNC" DRIFT_CLASSIFICATIONS = { "DOC_CHANGED", "PROMPT_CHANGED", @@ -36,15 +94,26 @@ UNBASELINED_CLASSIFICATION = "UNBASELINED" FAILURE_CLASSIFICATION = "FAILURE" +# Issue #884 coarse verdict statuses (status / reasons / affected_artifacts / +# remediation is the report shape the drift classifier converges on). +STATUS_CURRENT = "current" +STATUS_STALE = "stale" +STATUS_STAMPED = "stamped" +STATUS_CONFLICT = "conflict" +STATUS_UNBASELINED = "unbaselined" +STATUS_FAILURE = "failure" -@dataclass(frozen=True) -class SyncUnit: - """A prompt-derived unit discovered for deterministic classification.""" - basename: str - language: str - prompt_path: Path - prompts_dir: Path +def _norm(value: Any) -> Any: + """Normalise empty containers / falsey hashes to ``None`` for comparison. + + Mirrors the stamper's ``(x or None)`` currency check so an absent artifact + (``None``) and an empty ``{}`` map compare equal. + """ + return value or None + + +# --- Project root ------------------------------------------------------------ def project_root(start: Optional[Path] = None) -> Path: @@ -70,233 +139,380 @@ def project_root(start: Optional[Path] = None) -> Path: return current -def _prompts_dir_for(prompt_path: Path) -> Path: - """Return the concrete prompts directory to pass into path resolution.""" - return prompt_path.parent +@contextlib.contextmanager +def _chdir(root: Path): + """Run with ``cwd == root`` so resolution + dep keys are repo-relative. + + pdd's ``calculate_prompt_hash`` resolves refs against ``Path.cwd()`` + and stores ``include_deps`` keys relative to it; the committed fingerprints use + repo-relative keys, so hashing must run from the project root to match. + """ + prev = Path.cwd() + os.chdir(root) + try: + yield + finally: + os.chdir(prev) + + +# --- Repo layout ------------------------------------------------------------- + + +@dataclass(frozen=True) +class _Layout: # pylint: disable=too-many-instance-attributes + """Resolved repo paths a reconcile run operates on.""" + + root: Path + prompts_root: Path + meta_dir: Path + context_root: Path + tests_root: Path + code_root: Path + architecture_file: Path + waivers_file: Path + + +def _layout_for(root: Path) -> _Layout: + """Derive the repo layout from ``root`` (the PDD project root). + + Prompts live under ``pdd/prompts`` in a PDD-managed repo; a ``prompts`` + symlink/dir at the root (the repo's ``prompts -> pdd/prompts`` shim, or a + consumer whose prompts sit at the top level) is accepted as a fallback. + """ + root = root.resolve() + prompts_root = root / "pdd" / "prompts" + if not prompts_root.exists() and (root / "prompts").exists(): + prompts_root = root / "prompts" + return _Layout( + root=root, + prompts_root=prompts_root, + meta_dir=root / ".pdd" / "meta", + context_root=root / "context", + tests_root=root / "tests", + code_root=root / "pdd", + architecture_file=root / "architecture.json", + waivers_file=root / "scripts" / "fingerprint_waivers.json", + ) -def _prompt_units(prompt_root: Path) -> List[SyncUnit]: - units: List[SyncUnit] = [] - for prompt_path in sorted(prompt_root.rglob("*_*.prompt")): - basename, language = infer_module_identity(prompt_path) - if basename is None or language is None: +# --- architecture.json resolution -------------------------------------------- +# pdd's get_pdd_file_paths consults architecture.json FIRST for a module's code +# filepath (issue #225) and disambiguates the example/test stem for a bare leaf +# that maps to more than one module (issue #1677). Both are pure JSON+path logic; +# they are mirrored here (matching scripts/stamp_fingerprints.py byte-for-byte) +# because get_pdd_file_paths otherwise flattens a subdir'd basename without an +# architecture entry (commands/firecrawl -> pdd/firecrawl.py instead of the real +# pdd/commands/firecrawl.py). + +_ArchMaps = Tuple[Dict[str, set], Dict[str, set], frozenset] +_ARCH_CACHE: Dict[Path, _ArchMaps] = {} + + +def _load_architecture(architecture_file: Path) -> _ArchMaps: + """Return ``(by_filename, by_leaf, ambiguous_leaves)`` from architecture.json.""" + cached = _ARCH_CACHE.get(architecture_file) + if cached is not None: + return cached + by_filename: Dict[str, set] = {} + by_leaf: Dict[str, set] = {} + if not architecture_file.is_file(): + result: _ArchMaps = (by_filename, by_leaf, frozenset()) + _ARCH_CACHE[architecture_file] = result + return result + try: + data = json.loads(architecture_file.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + result = (by_filename, by_leaf, frozenset()) + _ARCH_CACHE[architecture_file] = result + return result + if isinstance(data, list): + modules = data + elif isinstance(data, dict): + modules = data.get("modules", []) + else: + modules = [] + for module in modules: + if not isinstance(module, dict): continue - units.append( - SyncUnit( - basename=basename, - language=language, - prompt_path=prompt_path, - prompts_dir=_prompts_dir_for(prompt_path), - ) - ) - return units + filename = str(module.get("filename") or "").strip() + filepath = str(module.get("filepath") or "").strip() + if not filename or not filepath or filename.endswith("_LLM.prompt"): + continue + fp = Path(filepath).as_posix() + by_filename.setdefault(filename.lower(), set()).add(fp) + by_leaf.setdefault(Path(filename).name.lower(), set()).add(fp) + ambiguous = frozenset( + leaf[: -len(f"_{LANGUAGE}.prompt")] + for leaf, fps in by_leaf.items() + if leaf.endswith(f"_{LANGUAGE}.prompt") and len(fps) > 1 + ) + result = (by_filename, by_leaf, ambiguous) + _ARCH_CACHE[architecture_file] = result + return result + + +def _resolve_code_and_stem( + basename: str, layout: _Layout, arch_maps: _ArchMaps +) -> Tuple[Path, str]: + """Return ``(code_path, artifact_stem)`` mirroring pdd's resolution. + + ``code_path`` is the architecture.json filepath when the prompt is listed + there, else ``pdd/.py`` (subdirectory preserved). ``artifact_stem`` + is the example/test stem: the code file's stem, replaced by a disambiguated + ``_safe_basename()`` when the bare leaf is ambiguous. + """ + by_filename, by_leaf, ambiguous = arch_maps + leaf = basename.rsplit("/", 1)[-1] + pf_full = f"{basename}_{LANGUAGE}.prompt".lower() + pf_leaf = f"{leaf}_{LANGUAGE}.prompt".lower() + + arch_fp: Optional[str] = None + full_fps = by_filename.get(pf_full) + if full_fps and len(full_fps) == 1: + arch_fp = next(iter(full_fps)) + if arch_fp is None: + leaf_fps = by_leaf.get(pf_leaf, set()) + if len(leaf_fps) == 1: + arch_fp = next(iter(leaf_fps)) + elif len(leaf_fps) > 1: + aligned = [ + fp + for fp in leaf_fps + if Path(fp).with_suffix("").as_posix().endswith(basename) + ] + if len(aligned) == 1: + arch_fp = aligned[0] + + if arch_fp: + code = layout.root / arch_fp + if leaf in ambiguous: + stem = _safe_basename(Path(arch_fp).with_suffix("").as_posix()) + else: + stem = Path(arch_fp).stem + else: + code = layout.code_root / f"{basename}.py" + stem = leaf + return code, stem -def _matches_module(unit: SyncUnit, wanted: set[str]) -> bool: - return ( - unit.basename in wanted - or _safe_basename(unit.basename) in wanted - or unit.prompt_path.stem in wanted +# --- Unit enumeration & path resolution -------------------------------------- + + +@dataclass(frozen=True) +class Unit: # pylint: disable=too-many-instance-attributes + """A single PDD dev unit resolved from a ``*_python.prompt`` file.""" + + basename: str + language: str + prompt: Path + code: Path + example: Path + test: Path + test_files: Tuple[Path, ...] + meta: Path + + +def _discover_test_files(test_dir: Path, stem: str) -> List[Path]: + """Mirror pdd's Bug #156 globbing: sorted ``test_*.py`` in ``test_dir``.""" + primary = test_dir / f"test_{stem}.py" + if test_dir.is_dir(): + pattern = glob.escape(f"test_{stem}") + matches = sorted(test_dir.glob(f"{pattern}*.py")) + else: + matches = [primary] if primary.exists() else [] + return matches or [primary] + + +def _build_unit(basename: str, prompt: Path, layout: _Layout, arch_maps: _ArchMaps) -> Unit: + """Resolve every artifact path for ``basename`` (stamper-parity resolution).""" + subdir = str(Path(basename).parent) if "/" in basename else "" + code, stem = _resolve_code_and_stem(basename, layout, arch_maps) + example_dir = layout.context_root / subdir if subdir else layout.context_root + test_dir = layout.tests_root / subdir if subdir else layout.tests_root + return Unit( + basename=basename, + language=LANGUAGE, + prompt=prompt, + code=code, + example=example_dir / f"{stem}_example.py", + test=test_dir / f"test_{stem}.py", + test_files=tuple(_discover_test_files(test_dir, stem)), + meta=layout.meta_dir / f"{_safe_basename(basename)}_{LANGUAGE}.json", ) -def _metadata_identity(path: Path) -> Optional[tuple[str, str]]: - stem = path.stem - if stem.endswith("_run") or "_" not in stem: +def infer_basename(prompt_path: Path, prompts_root: Path) -> Optional[str]: + """Return the unit basename for a ``*_python.prompt`` file, or None. + + Basename is the path relative to ``prompts_root`` with the ``_python.prompt`` + suffix dropped and subdirectories preserved (e.g. ``commands/which``). + """ + name = prompt_path.name + if not name.endswith(PROMPT_SUFFIX): return None - basename, language = stem.rsplit("_", 1) - if not basename or not language: + try: + rel = prompt_path.relative_to(prompts_root) + except ValueError: return None - return basename, language - + stem = rel.name[: -len(PROMPT_SUFFIX)] + subdir = rel.parent + if str(subdir) == ".": + return stem + return (subdir / stem).as_posix() -def _module_token_basename(token: str, language: str) -> str: - basename = token[:-7] if token.endswith(".prompt") else token - language_suffix = f"_{language}" - if basename.endswith(language_suffix): - return basename[: -len(language_suffix)] - return basename +def enumerate_units( + layout: _Layout, + arch_maps: _ArchMaps, + modules: Optional[Iterable[str]] = None, +) -> List[Unit]: + """Return every python unit under the prompts root, sorted by basename. -def _requested_basename_for_identity( - identity: tuple[str, str], - wanted: set[str], -) -> Optional[str]: - safe_basename, language = identity - for item in sorted(wanted): - basename = _module_token_basename(item, language) - if basename == safe_basename or _safe_basename(basename) == safe_basename: - return basename - return None + ``modules`` (a set of basenames, safe-basenames or prompt stems) filters the + result; ``None`` returns all units. + """ + wanted = set(modules or []) + units: List[Unit] = [] + if not layout.prompts_root.exists(): + return units + for prompt in sorted(layout.prompts_root.rglob(f"*{PROMPT_SUFFIX}")): + basename = infer_basename(prompt, layout.prompts_root) + if basename is None: + continue + if wanted and not _unit_wanted(basename, prompt, wanted): + continue + units.append(_build_unit(basename, prompt, layout, arch_maps)) + return units -def _identity_matches_wanted(identity: tuple[str, str], wanted: set[str]) -> bool: - safe_basename, language = identity +def _unit_wanted(basename: str, prompt: Path, wanted: set) -> bool: + """Match a unit against ``--module`` / ``[BASENAME]`` selectors.""" return ( - safe_basename in wanted - or f"{safe_basename}_{language}" in wanted - or f"{safe_basename}_{language}.prompt" in wanted - or _requested_basename_for_identity(identity, wanted) is not None + basename in wanted + or _safe_basename(basename) in wanted + or prompt.stem in wanted + or basename.rsplit("/", 1)[-1] in wanted ) -def _prompt_path_for_basename(prompt_root: Path, basename: str, language: str) -> Path: - parts = Path(basename).parts - if len(parts) <= 1: - return prompt_root / f"{basename}_{language}.prompt" - return prompt_root.joinpath(*parts[:-1], f"{parts[-1]}_{language}.prompt") - - -def _slash_candidates(safe_basename: str) -> List[str]: - parts = safe_basename.split("_") - if len(parts) <= 1: - return [] - - candidates: List[str] = [] - separators = range(1, len(parts)) - for count in range(1, len(parts)): - for slash_positions in combinations(separators, count): - chunks: List[str] = [parts[0]] - for index, part in enumerate(parts[1:], start=1): - if index in slash_positions: - chunks.append("/") - else: - chunks.append("_") - chunks.append(part) - candidates.append("".join(chunks)) - return candidates - - -def _existing_artifact_score( - basename: str, - language: str, - prompt_root: Path, -) -> int: - try: - paths = get_pdd_file_paths(basename, language, prompts_dir=str(prompt_root)) - except Exception: - return 0 - score = 0 - for artifact in ("code", "example", "test"): - path = paths.get(artifact) - if path is not None and path.exists(): - score += 1 - return score - - -def _infer_basename_from_artifacts( - safe_basename: str, - language: str, - prompt_root: Path, -) -> str: - best = safe_basename - best_score = _existing_artifact_score(best, language, prompt_root) - for candidate in _slash_candidates(safe_basename): - score = _existing_artifact_score(candidate, language, prompt_root) - if score > best_score: - best = candidate - best_score = score - return best - - -def _unit_from_metadata_identity( - identity: tuple[str, str], - prompt_root: Path, - prompt_index: Dict[tuple[str, str], SyncUnit], - requested_basename: Optional[str] = None, -) -> SyncUnit: - safe_basename, language = identity - prompt_unit = prompt_index.get((safe_basename, language)) - if prompt_unit is not None: - return prompt_unit - - basename = requested_basename or _infer_basename_from_artifacts( - safe_basename, - language, - prompt_root, - ) - prompt_path = _prompt_path_for_basename(prompt_root, basename, language) - return SyncUnit( - basename=basename, - language=language, - prompt_path=prompt_path, - prompts_dir=prompt_root, - ) +# --- .pddignore & waivers ---------------------------------------------------- -def _metadata_identities(meta_root: Path) -> List[tuple[str, str]]: - identities: List[tuple[str, str]] = [] - seen: set[tuple[str, str]] = set() - if not meta_root.exists(): - return identities - for path in sorted(meta_root.glob("*_*.json")): - identity = _metadata_identity(path) - if identity is None or identity in seen: +def load_pddignore(root: Path) -> List[str]: + """Load ``.pddignore`` patterns from ``root`` (comments/blank stripped).""" + path = root / ".pddignore" + patterns: List[str] = [] + if not path.is_file(): + return patterns + for line in path.read_text(encoding="utf-8").splitlines(): + line = line.strip() + if not line or line.startswith("#"): continue - seen.add(identity) - identities.append(identity) - return identities + patterns.append(line) + return patterns -def discover_units( - root: Optional[Path] = None, - modules: Optional[Iterable[str]] = None, -) -> List[SyncUnit]: - """Discover prompt-backed units under ``root``.""" - base = project_root(root) - wanted = set(modules or []) - prompt_root = base / "prompts" - prompt_units = _prompt_units(prompt_root) if prompt_root.exists() else [] - meta_root = base / ".pdd" / "meta" - metadata_identities = _metadata_identities(meta_root) - - prompt_index: Dict[tuple[str, str], SyncUnit] = {} - for unit in prompt_units: - prompt_index.setdefault((_safe_basename(unit.basename), unit.language), unit) - - if wanted: - units: List[SyncUnit] = [] - seen: set[tuple[str, str, Path]] = set() - for identity in metadata_identities: - if not _identity_matches_wanted(identity, wanted): - continue - unit = _unit_from_metadata_identity( - identity, - prompt_root, - prompt_index, - requested_basename=_requested_basename_for_identity(identity, wanted), - ) - dedupe_key = (unit.basename, unit.language, unit.prompt_path) - if dedupe_key in seen: - continue - seen.add(dedupe_key) - units.append(unit) - for unit in prompt_units: - if not _matches_module(unit, wanted): - continue - dedupe_key = (unit.basename, unit.language, unit.prompt_path) - if dedupe_key in seen: - continue - seen.add(dedupe_key) - units.append(unit) - return units +def is_pddignored(code_path: Path, patterns: List[str], root: Path) -> bool: + """Mirror update_main._is_pddignored against the repo-relative code path.""" + try: + rel_path = code_path.resolve().relative_to(root.resolve()).as_posix() + except ValueError: + return False + basename = code_path.name + for pat in patterns: + if pat.endswith("/"): + dir_name = pat.rstrip("/") + parts = rel_path.split("/") + if dir_name in parts[:-1]: + return True + else: + if fnmatch.fnmatch(rel_path, pat): + return True + if fnmatch.fnmatch(basename, pat): + return True + return False - if not metadata_identities: - return prompt_units - units: List[SyncUnit] = [] - seen: set[tuple[str, str, Path]] = set() - for identity in metadata_identities: - unit = _unit_from_metadata_identity(identity, prompt_root, prompt_index) - dedupe_key = (unit.basename, unit.language, unit.prompt_path) - if dedupe_key in seen: - continue - seen.add(dedupe_key) - units.append(unit) - return units +def load_waivers(waivers_file: Path) -> Dict[str, str]: + """Return ``{basename: reason}`` from the committed waiver file.""" + if not waivers_file.is_file(): + return {} + try: + data = json.loads(waivers_file.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + return {} + waivers: Dict[str, str] = {} + for entry in data.get("waivers", []): + if isinstance(entry, dict) and entry.get("basename"): + waivers[entry["basename"]] = entry.get("reason", "") + return waivers + + +def partition_units( + units: List[Unit], pddignore: List[str], waivers: Dict[str, str], root: Path +) -> Tuple[List[Unit], List[Unit], List[Unit], List[Unit]]: + """Split units into ``(stampable, ignored, waived, no_code)`` buckets. + + * ignored: code path matches ``.pddignore`` (pdd never tracks these). + * waived: basename appears in the committed waiver file. + * no_code: code file absent and not waived (nothing to hash). + * stampable: everything else. + """ + stampable: List[Unit] = [] + ignored: List[Unit] = [] + waived: List[Unit] = [] + no_code: List[Unit] = [] + for unit in units: + if is_pddignored(unit.code, pddignore, root): + ignored.append(unit) + elif unit.basename in waivers: + waived.append(unit) + elif not unit.code.exists(): + no_code.append(unit) + else: + stampable.append(unit) + return stampable, ignored, waived, no_code + + +# --- Hashing (pdd's real functions) ------------------------------------------ + + +def _paths_for_hashing(unit: Unit) -> Dict[str, Any]: + """Build the ``paths`` dict pdd's ``calculate_current_hashes`` expects.""" + return { + "prompt": unit.prompt, + "code": unit.code, + "example": unit.example, + "test": unit.test, + "test_files": list(unit.test_files), + } + + +def compute_current_hashes( + unit: Unit, stored_deps: Optional[Dict[str, str]] = None +) -> Dict[str, Any]: + """Recompute all fingerprint hash fields for ``unit`` via pdd's real hasher. + + Must run under ``_chdir(root)`` so resolution matches the committed + fingerprints. + """ + return calculate_current_hashes( + _paths_for_hashing(unit), stored_include_deps=stored_deps + ) -def _load_fingerprint_json(path: Path) -> tuple[Optional[Dict[str, Any]], Optional[str]]: +def _read_fingerprint_obj(unit: Unit) -> Optional[Fingerprint]: + """Read ``unit``'s committed fingerprint, or None if missing/invalid. + + ``get_fingerprint_path(basename, paths=...)`` resolves to ``unit.meta`` (pinned + by the resolution parity check), so read_fingerprint reads the same file the + stamper writes. + """ + return read_fingerprint(unit.basename, unit.language, paths=_paths_for_hashing(unit)) + + +def _load_fingerprint_json(path: Path) -> Tuple[Optional[Dict[str, Any]], Optional[str]]: + """Return ``(data, error)`` distinguishing a missing vs unparseable meta.""" if not path.exists(): return None, "missing" try: @@ -308,175 +524,55 @@ def _load_fingerprint_json(path: Path) -> tuple[Optional[Dict[str, Any]], Option return data, None -def _paths_as_json(paths: Dict[str, Any], root: Path) -> Dict[str, Any]: - payload: Dict[str, Any] = {} - for key, value in paths.items(): - if isinstance(value, Path): - try: - payload[key] = value.resolve().relative_to(root.resolve()).as_posix() - except (OSError, ValueError): - payload[key] = str(value) - elif isinstance(value, list): - payload[key] = [str(item) for item in value] - else: - payload[key] = str(value) - return payload +def _hashes_equal(stored: Fingerprint, current: Dict[str, Any]) -> bool: + """True iff every content hash field matches (the currency test).""" + return all( + _norm(getattr(stored, field_name, None)) == _norm(current.get(field_name)) + for field_name in HASH_FIELDS + ) + + +# --- Classification ---------------------------------------------------------- def _changed_artifacts( - fingerprint: Fingerprint, - paths: Dict[str, Path], - current_hashes: Dict[str, Any], + fingerprint: Fingerprint, paths: Dict[str, Any], current_hashes: Dict[str, Any] ) -> List[str]: + """Return the changed artifact labels (doc/prompt/code/example/test).""" changes: List[str] = [] - if current_hashes.get("prompt_hash") != fingerprint.prompt_hash: - if (current_hashes.get("include_deps") or {}) != ( - fingerprint.include_deps or {} - ): + if _norm(current_hashes.get("prompt_hash")) != _norm(fingerprint.prompt_hash): + if _norm(current_hashes.get("include_deps")) != _norm(fingerprint.include_deps): changes.append("doc") else: changes.append("prompt") if ( paths.get("code") and paths["code"].exists() - and current_hashes.get("code_hash") != fingerprint.code_hash + and _norm(current_hashes.get("code_hash")) != _norm(fingerprint.code_hash) ): changes.append("code") if ( paths.get("example") and paths["example"].exists() - and current_hashes.get("example_hash") != fingerprint.example_hash + and _norm(current_hashes.get("example_hash")) != _norm(fingerprint.example_hash) ): changes.append("example") if ( paths.get("test") and paths["test"].exists() - and current_hashes.get("test_hash") != fingerprint.test_hash + and _norm(current_hashes.get("test_hash")) != _norm(fingerprint.test_hash) ): changes.append("test") return changes -def _missing_fingerprinted_artifacts( - fingerprint: Fingerprint, - paths: Dict[str, Path], -) -> List[str]: - missing: List[str] = [] - field_by_artifact = { - "prompt": "prompt_hash", - "code": "code_hash", - "example": "example_hash", - "test": "test_hash", - } - for artifact, field in field_by_artifact.items(): - path = paths.get(artifact) - if getattr(fingerprint, field) and (path is None or not path.exists()): - missing.append(artifact) - return missing - - -def _artifact_search_name( - artifact: str, - basename: str, - expected_path: Path, -) -> Optional[str]: - suffix = expected_path.suffix - leaf = Path(basename).name - if artifact == "code": - return f"{leaf}{suffix}" - if artifact == "example": - return f"{leaf}_example{suffix}" - if artifact == "test": - return f"test_{leaf}{suffix}" - return None - - -def _find_matching_artifact( - root: Path, - filename: str, - expected_hash: str, -) -> Optional[Path]: - matches: List[Path] = [] - for candidate in root.rglob(filename): - if any(part in {".git", ".pdd", "__pycache__"} for part in candidate.parts): - continue - if candidate.is_file() and calculate_sha256(candidate) == expected_hash: - matches.append(candidate) - if len(matches) == 1: - return matches[0] - return None - - -def _repair_missing_fingerprinted_paths( - paths: Dict[str, Path], - fingerprint: Fingerprint, - basename: str, - root: Path, -) -> Dict[str, Path]: - repaired = dict(paths) - field_by_artifact = { - "code": "code_hash", - "example": "example_hash", - "test": "test_hash", - } - for artifact, field in field_by_artifact.items(): - path = repaired.get(artifact) - expected_hash = getattr(fingerprint, field) - if path is None or path.exists() or not expected_hash: - continue - filename = _artifact_search_name(artifact, basename, path) - if not filename: - continue - match = _find_matching_artifact(root, filename, expected_hash) - if match is None: - continue - repaired[artifact] = match - if artifact == "test": - repaired["test_files"] = [match] - return repaired - - -def _missing_required_hashes(fingerprint: Fingerprint, paths: Dict[str, Path]) -> List[str]: - missing: List[str] = [] - field_by_artifact = { - "prompt": "prompt_hash", - "code": "code_hash", - "example": "example_hash", - "test": "test_hash", - } - for artifact, field in field_by_artifact.items(): - path = paths.get(artifact) - if path is not None and path.exists() and not getattr(fingerprint, field): - missing.append(field) - return missing - - -def _operation_for(classification: str, changes: List[str]) -> str: - # pylint: disable=too-many-return-statements - if classification == "IN_SYNC": - return "nothing" - if classification == "DOC_CHANGED": - return "reconcile" - if classification == "PROMPT_CHANGED": - return "generate" - if classification == "CODE_CHANGED": - return "update" - if classification == "TEST_CHANGED": - return "test" - if classification == "EXAMPLE_CHANGED": - return "verify" - if classification == "CONFLICT": - return "conflict" - if classification in {"UNBASELINED", "FAILURE"}: - return "none" - if "code" in changes or "example" in changes: - return "verify" - if "test" in changes: - return "test" - return "reconcile" - - def _classification_for_changes(changes: List[str]) -> str: + """Map changed artifacts to a classification. + + CONFLICT is prompt-side (prompt/doc) AND code/derived-side both moved — the + same definition the sync decision path uses (issue #1929 owns that path; this + keeps the two aligned). + """ # pylint: disable=too-many-return-statements derived = [item for item in changes if item not in {"prompt", "doc"}] if any(item in changes for item in ("prompt", "doc")) and derived: @@ -493,160 +589,206 @@ def _classification_for_changes(changes: List[str]) -> str: return "EXAMPLE_CHANGED" if changes: return "DERIVED_CHANGED" - return "IN_SYNC" + return IN_SYNC_CLASSIFICATION -def classify_unit(unit: SyncUnit, root: Optional[Path] = None) -> Dict[str, Any]: - # pylint: disable=broad-exception-caught - """Classify one sync unit without mutating files.""" - base = project_root(root) - try: - paths = get_pdd_file_paths( - unit.basename, - unit.language, - prompts_dir=str(unit.prompts_dir), - ) - except Exception as exc: # pragma: no cover - surfaced in JSON report - return { - "basename": unit.basename, - "language": unit.language, - "classification": FAILURE_CLASSIFICATION, - "operation": "none", - "reason": f"path resolution failed: {exc}", - "changed_files": [], - "metadata_valid": False, - "paths": {"prompt": str(unit.prompt_path)}, - } +def _operation_for(classification: str, changes: List[str]) -> str: + """Map a classification to the pdd operation that would resolve it.""" + mapping = { + IN_SYNC_CLASSIFICATION: "nothing", + "DOC_CHANGED": "reconcile", + "PROMPT_CHANGED": "generate", + "CODE_CHANGED": "update", + "TEST_CHANGED": "test", + "EXAMPLE_CHANGED": "verify", + CONFLICT_CLASSIFICATION: "conflict", + UNBASELINED_CLASSIFICATION: "none", + FAILURE_CLASSIFICATION: "none", + } + if classification in mapping: + return mapping[classification] + if "code" in changes or "example" in changes: + return "verify" + if "test" in changes: + return "test" + return "reconcile" - fp_path = get_fingerprint_path(unit.basename, unit.language, paths=paths) - _raw_fp, raw_error = _load_fingerprint_json(fp_path) - if raw_error is not None: - return { - "basename": unit.basename, - "language": unit.language, - "classification": UNBASELINED_CLASSIFICATION, - "operation": "none", - "reason": f"fingerprint {raw_error}", - "changed_files": [], - "metadata_valid": False, - "fingerprint_path": str(fp_path), - "paths": _paths_as_json(paths, base), - } - fingerprint = read_fingerprint(unit.basename, unit.language, paths=paths) - if fingerprint is None: - return { - "basename": unit.basename, - "language": unit.language, - "classification": UNBASELINED_CLASSIFICATION, - "operation": "none", - "reason": "fingerprint invalid", - "changed_files": [], - "metadata_valid": False, - "fingerprint_path": str(fp_path), - "paths": _paths_as_json(paths, base), - } +def _status_for(classification: str) -> str: + """Map a classification to the coarse issue #884 status.""" + if classification == IN_SYNC_CLASSIFICATION: + return STATUS_CURRENT + if classification in DRIFT_CLASSIFICATIONS: + return STATUS_STALE + if classification == CONFLICT_CLASSIFICATION: + return STATUS_CONFLICT + if classification == UNBASELINED_CLASSIFICATION: + return STATUS_UNBASELINED + return STATUS_FAILURE - if not unit.prompt_path.exists(): - paths = _repair_missing_fingerprinted_paths( - paths, - fingerprint, - unit.basename, - base, - ) - missing_hashes = _missing_required_hashes(fingerprint, paths) - if missing_hashes: - return { - "basename": unit.basename, - "language": unit.language, - "classification": FAILURE_CLASSIFICATION, - "operation": "none", - "reason": "incomplete metadata: " + ", ".join(sorted(missing_hashes)), - "changed_files": [], - "metadata_valid": False, - "fingerprint_path": str(fp_path), - "paths": _paths_as_json(paths, base), - "failure": "incomplete_metadata", - } +def _remediation_for(basename: str, classification: str) -> str: + """Suggested next command for a non-current unit.""" + if classification in (IN_SYNC_CLASSIFICATION, FAILURE_CLASSIFICATION): + return "" + if classification == "PROMPT_CHANGED": + return f"pdd sync {basename}" + if classification == "CODE_CHANGED": + return f"pdd update {basename}" + if classification == CONFLICT_CLASSIFICATION: + return f"pdd reconcile {basename} --accept-current # or resolve the conflict" + if classification == UNBASELINED_CLASSIFICATION: + return f"pdd reconcile {basename} --backfill" + # DOC/TEST/EXAMPLE/DERIVED — a plain reconcile stamp is the fix. + return f"pdd reconcile {basename}" - missing_artifacts = _missing_fingerprinted_artifacts(fingerprint, paths) - if missing_artifacts: - return { - "basename": unit.basename, - "language": unit.language, - "classification": FAILURE_CLASSIFICATION, - "operation": "none", - "reason": "missing fingerprinted artifacts: " - + ", ".join(sorted(missing_artifacts)), - "changed_files": missing_artifacts, - "metadata_valid": True, - "fingerprint_path": str(fp_path), - "paths": _paths_as_json(paths, base), - "failure": "missing_artifacts", - } - current_hashes = calculate_current_hashes( - paths, - stored_include_deps=fingerprint.include_deps, - ) - changes = _changed_artifacts(fingerprint, paths, current_hashes) - classification = _classification_for_changes(changes) - return { +def _rel(path: Path, root: Path) -> str: + try: + return path.resolve().relative_to(root.resolve()).as_posix() + except (OSError, ValueError): + return str(path) + + +def _verdict( + unit: Unit, + layout: _Layout, + *, + classification: str, + changes: List[str], + reason: str, + metadata_valid: bool, + current_hashes: Optional[Dict[str, Any]] = None, +) -> Dict[str, Any]: + # pylint: disable=too-many-arguments + """Assemble one unit's report entry (legacy fields + issue #884 shape).""" + entry: Dict[str, Any] = { "basename": unit.basename, "language": unit.language, "classification": classification, + "status": _status_for(classification), "operation": _operation_for(classification, changes), - "reason": ( - "all hashes match fingerprint" - if classification == "IN_SYNC" - else f"{', '.join(changes)} changed since fingerprint" - ), + "reason": reason, + "reasons": [reason] if reason else [], "changed_files": changes, - "metadata_valid": True, - "fingerprint_path": str(fp_path), - "paths": _paths_as_json(paths, base), - "hashes": { + "affected_artifacts": changes, + "remediation": _remediation_for(unit.basename, classification), + "metadata_valid": metadata_valid, + "fingerprint_path": _rel(unit.meta, layout.root), + "paths": { + "prompt": _rel(unit.prompt, layout.root), + "code": _rel(unit.code, layout.root), + "example": _rel(unit.example, layout.root), + "test": _rel(unit.test, layout.root), + "test_files": [_rel(p, layout.root) for p in unit.test_files], + }, + } + if current_hashes is not None: + entry["hashes"] = { "prompt_hash": current_hashes.get("prompt_hash"), "code_hash": current_hashes.get("code_hash"), "example_hash": current_hashes.get("example_hash"), "test_hash": current_hashes.get("test_hash"), - }, - } + } + return entry + + +def classify_unit(unit: Unit, layout: _Layout) -> Dict[str, Any]: + """Classify one unit without mutating files. Runs under ``_chdir(root)``.""" + _raw, raw_error = _load_fingerprint_json(unit.meta) + if raw_error is not None: + return _verdict( + unit, + layout, + classification=UNBASELINED_CLASSIFICATION, + changes=[], + reason=f"fingerprint {raw_error}", + metadata_valid=False, + ) + fingerprint = _read_fingerprint_obj(unit) + if fingerprint is None: + return _verdict( + unit, + layout, + classification=UNBASELINED_CLASSIFICATION, + changes=[], + reason="fingerprint invalid", + metadata_valid=False, + ) + current = compute_current_hashes(unit, fingerprint.include_deps) + changes = _changed_artifacts(fingerprint, _paths_for_hashing(unit), current) + classification = _classification_for_changes(changes) + reason = ( + "all hashes match fingerprint" + if classification == IN_SYNC_CLASSIFICATION + else f"{', '.join(changes)} changed since fingerprint" + ) + return _verdict( + unit, + layout, + classification=classification, + changes=changes, + reason=reason, + metadata_valid=True, + current_hashes=current, + ) + + +# --- Stamping (idempotent, byte-identical to pdd sync) ----------------------- + + +def stamp_unit(unit: Unit) -> bool: + """Stamp ``unit``'s fingerprint to the current tree iff its hashes changed. + + Idempotent by construction: a unit whose content hashes already match the + stored fingerprint is NOT rewritten (its timestamp is preserved and no file is + written), so a second consecutive run is a no-op and unchanged units never + churn (issue #1932 / pdd_cloud restamp-churn addendum). Returns True iff a + file was written. Must run under ``_chdir(root)``. + """ + stored = _read_fingerprint_obj(unit) + current = compute_current_hashes( + unit, stored.include_deps if stored is not None else None + ) + if stored is not None and _hashes_equal(stored, current): + return False + command = NEW_UNIT_COMMAND + if stored is not None and stored.command: + command = stored.command + save_fingerprint(unit.basename, unit.language, command, paths=_paths_for_hashing(unit)) + return True + + +# --- Reporting --------------------------------------------------------------- def _build_summary(units: List[Dict[str, Any]]) -> Dict[str, int]: return { "metadata_stale": sum( - 1 for unit in units if unit["classification"] in DRIFT_CLASSIFICATIONS + 1 for u in units if u["classification"] in DRIFT_CLASSIFICATIONS ), "conflicts": sum( - 1 for unit in units if unit["classification"] == CONFLICT_CLASSIFICATION + 1 for u in units if u["classification"] == CONFLICT_CLASSIFICATION ), "unbaselined": sum( - 1 - for unit in units - if unit["classification"] == UNBASELINED_CLASSIFICATION + 1 for u in units if u["classification"] == UNBASELINED_CLASSIFICATION ), "failures": sum( - 1 for unit in units if unit["classification"] == FAILURE_CLASSIFICATION + 1 for u in units if u["classification"] == FAILURE_CLASSIFICATION ), - "synced": sum(1 for unit in units if unit["classification"] == "IN_SYNC"), + "synced": sum(1 for u in units if u["classification"] == IN_SYNC_CLASSIFICATION), + "stamped": sum(1 for u in units if u.get("status") == STATUS_STAMPED), "total": len(units), } -def _append_ledger( - root: Path, - consumer: str, - units: List[Dict[str, Any]], -) -> Optional[str]: +def _append_ledger(root: Path, consumer: str, units: List[Dict[str, Any]]) -> Optional[str]: ledger_path = root / ".pdd" / "drift-ledger.jsonl" ledger_path.parent.mkdir(parents=True, exist_ok=True) wrote = False with ledger_path.open("a", encoding="utf-8") as handle: for unit in units: - if unit["classification"] == "IN_SYNC": + if unit["classification"] == IN_SYNC_CLASSIFICATION: continue entry = { "timestamp": datetime.now(timezone.utc).isoformat(), @@ -654,6 +796,7 @@ def _append_ledger( "basename": unit["basename"], "language": unit["language"], "classification": unit["classification"], + "status": unit.get("status"), "operation": unit["operation"], "changed_files": unit.get("changed_files", []), "reason": unit.get("reason", ""), @@ -663,30 +806,20 @@ def _append_ledger( return str(ledger_path) if wrote else None -def _heal_units( - units: List[SyncUnit], - classified: List[Dict[str, Any]], -) -> List[str]: - healed: List[str] = [] - by_key = {(unit.basename, unit.language): unit for unit in units} - for item in classified: - if item["classification"] not in DRIFT_CLASSIFICATIONS: - continue - unit = by_key.get((item["basename"], item["language"])) - if unit is None: - continue - paths = get_pdd_file_paths( - unit.basename, - unit.language, - prompts_dir=str(unit.prompts_dir), - ) - fingerprint = read_fingerprint(unit.basename, unit.language, paths=paths) - operation = "fix" - if fingerprint and fingerprint.command in {"verify", "test", "fix", "update"}: - operation = fingerprint.command - save_fingerprint(unit.basename, unit.language, operation, paths, 0.0, "reconcile") - healed.append(unit.basename) - return healed +def _stampable_now(classification: str, *, accept_current: bool, backfill: bool) -> bool: + """Should a unit with this classification be stamped this run? + + Single-sided drift is always safe to stamp. CONFLICT (both sides moved) is + stamped only with an explicit ``--accept-current`` (the human declares the + current tree the agreed state); UNBASELINED only with ``--backfill``. + """ + if classification in DRIFT_CLASSIFICATIONS: + return True + if classification == CONFLICT_CLASSIFICATION: + return accept_current + if classification == UNBASELINED_CLASSIFICATION: + return backfill + return False def build_report( @@ -696,51 +829,143 @@ def build_report( modules: Optional[Iterable[str]] = None, heal: bool = False, ledger: bool = False, + accept_current: bool = False, + backfill: bool = False, ) -> Dict[str, Any]: - """Build a shared continuous-sync JSON report.""" + # pylint: disable=too-many-arguments,too-many-locals + """Build the shared continuous-sync report, optionally stamping safe cases. + + ``heal`` stamps single-sided drift; ``accept_current`` additionally stamps + CONFLICT units; ``backfill`` additionally stamps UNBASELINED units. Stamping + is idempotent and re-classifies afterwards so the reported status reflects the + post-stamp tree (a stamped unit becomes ``current`` with ``status=stamped``). + """ base = project_root(root) - units = discover_units(base, modules=modules) - classified = [classify_unit(unit, base) for unit in units] - healed = _heal_units(units, classified) if heal else [] - if healed: - classified = [classify_unit(unit, base) for unit in units] + layout = _layout_for(base) + arch_maps = _load_architecture(layout.architecture_file) + units = enumerate_units(layout, arch_maps, modules=modules) + pddignore = load_pddignore(layout.root) + waivers = load_waivers(layout.waivers_file) + stampable, _ignored, _waived, _no_code = partition_units( + units, pddignore, waivers, layout.root + ) + + do_stamp = heal or accept_current or backfill + stamped: List[str] = [] + with _chdir(layout.root): + classified = [classify_unit(u, layout) for u in stampable] + if do_stamp: + by_name = {u.basename: u for u in stampable} + for entry in classified: + if _stampable_now( + entry["classification"], + accept_current=accept_current, + backfill=backfill, + ): + unit = by_name.get(entry["basename"]) + if unit is not None and stamp_unit(unit): + stamped.append(unit.basename) + if stamped: + stamped_set = set(stamped) + classified = [classify_unit(u, layout) for u in stampable] + for entry in classified: + if entry["basename"] in stamped_set: + entry["status"] = STATUS_STAMPED + summary = _build_summary(classified) - ledger_path = _append_ledger(base, consumer, classified) if ledger else None + ledger_path = _append_ledger(layout.root, consumer, classified) if ledger else None ok = ( summary["metadata_stale"] == 0 and summary["conflicts"] == 0 and summary["unbaselined"] == 0 and summary["failures"] == 0 ) - report = { + report: Dict[str, Any] = { "ok": ok, "consumer": consumer, - "project_root": str(base), + "project_root": str(layout.root), "summary": summary, "metadata_stale": summary["metadata_stale"], "units": classified, - "drift": [ - unit - for unit in classified - if unit["classification"] in DRIFT_CLASSIFICATIONS - ], + "drift": [u for u in classified if u["classification"] in DRIFT_CLASSIFICATIONS], "conflicts": [ - unit - for unit in classified - if unit["classification"] == CONFLICT_CLASSIFICATION + u for u in classified if u["classification"] == CONFLICT_CLASSIFICATION ], "unbaselined": [ - unit - for unit in classified - if unit["classification"] == UNBASELINED_CLASSIFICATION + u for u in classified if u["classification"] == UNBASELINED_CLASSIFICATION ], "failures": [ - unit - for unit in classified - if unit["classification"] == FAILURE_CLASSIFICATION + u for u in classified if u["classification"] == FAILURE_CLASSIFICATION ], - "healed": healed, + "healed": stamped, + "stamped": stamped, } if ledger_path: report["ledger_path"] = ledger_path return report + + +# --- Verification (--check) -------------------------------------------------- + + +@dataclass +class CheckResult: + """Outcome of a read-only ``--check`` verification.""" + + ok: bool + stampable: int + ignored: int + waived: int + missing: List[str] = field(default_factory=list) + stale: List[Tuple[str, List[str]]] = field(default_factory=list) + no_code: List[str] = field(default_factory=list) + + +def run_check( + root: Optional[Path] = None, modules: Optional[Iterable[str]] = None +) -> CheckResult: + # pylint: disable=too-many-locals + """Verify committed fingerprints are current (read-only, no writes). + + Contract mirrors ``scripts/stamp_fingerprints.py --check``: waived/ignored + units are excluded; a stampable unit with a missing/invalid fingerprint or any + stale hash field, or an unwaived unit with no code file, makes the result not + ``ok``. + """ + base = project_root(root) + layout = _layout_for(base) + arch_maps = _load_architecture(layout.architecture_file) + units = enumerate_units(layout, arch_maps, modules=modules) + pddignore = load_pddignore(layout.root) + waivers = load_waivers(layout.waivers_file) + stampable, ignored, waived, no_code = partition_units( + units, pddignore, waivers, layout.root + ) + + missing: List[str] = [] + stale: List[Tuple[str, List[str]]] = [] + with _chdir(layout.root): + for unit in stampable: + stored = _read_fingerprint_obj(unit) + if stored is None: + missing.append(unit.basename) + continue + current = compute_current_hashes(unit, stored.include_deps) + diffs = [ + field_name + for field_name in HASH_FIELDS + if _norm(getattr(stored, field_name, None)) != _norm(current.get(field_name)) + ] + if diffs: + stale.append((unit.basename, diffs)) + unwaived_no_code = [u.basename for u in no_code] + ok = not (missing or stale or unwaived_no_code) + return CheckResult( + ok=ok, + stampable=len(stampable), + ignored=len(ignored), + waived=len(waived), + missing=sorted(missing), + stale=sorted(stale), + no_code=sorted(unwaived_no_code), + ) From 3dfefd639fd9ad3a7138035d7924ff0f7e34f225 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:34:04 -0700 Subject: [PATCH 22/30] Prompt catch-up: back-propagate checkup_prompt_apply (A2 pilot 4) pdd update (agentic, provider=google) back-propagated code->prompt for the code-ahead unit checkup_prompt_apply (queue rank 30, non-conflict). All public symbols (ApplyFindingRecord, ApplyRunResult, apply_approved_patches) retained. Code untouched; tests/test_checkup_prompt_apply.py 14 passed. Re-stamped; --check clean. Co-Authored-By: Claude --- .pdd/meta/checkup_prompt_apply_python.json | 6 +++--- .../checkup_prompt_apply_python.prompt | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/.pdd/meta/checkup_prompt_apply_python.json b/.pdd/meta/checkup_prompt_apply_python.json index a29db2941a..79fc7bc260 100644 --- a/.pdd/meta/checkup_prompt_apply_python.json +++ b/.pdd/meta/checkup_prompt_apply_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.299", - "timestamp": "2026-07-09T19:38:58.309570+00:00", - "command": "fix", - "prompt_hash": "95685575e722bfed5574086d8e01f31ec743e6f4046b101032748e7848efb14c", + "timestamp": "2026-07-09T20:33:49.040399+00:00", + "command": "update", + "prompt_hash": "6da60ee60615d16570497d688e47ef4d6d35ced3f2b033c5969755f1d8923118", "code_hash": "d72f795e03a2eb9b60023ee3f2e23975d10a61c7deb0daeb319030e5a1f92206", "example_hash": null, "test_hash": "c699ccf181590954e7155624838dd6d0f39cd81f958f18cd7e11276046e9282d", diff --git a/pdd/prompts/checkup_prompt_apply_python.prompt b/pdd/prompts/checkup_prompt_apply_python.prompt index fefa9d0a40..ce5b06bad1 100644 --- a/pdd/prompts/checkup_prompt_apply_python.prompt +++ b/pdd/prompts/checkup_prompt_apply_python.prompt @@ -21,18 +21,22 @@ Write `pdd/checkup_prompt_apply.py`. % Requirements - Validate approved patch kind and target path before any write. -- Allow prompt source targets including `pdd/prompts/**/*.prompt`, excluding `*_LLM.prompt`. -- Continue forbidding tests, generated/context paths, implementation files under `pdd/`, absolute paths, and traversal outside the repository root. -- In `--dry-run`, record accepted/rejected patches and write the apply log, but do not mutate files or create backups. -- For real applies, create backups under `.pdd/evidence/checkups/backups//`, write atomically, then run a deterministic postflight checkup. -- Any rejected approved patch must remain inspectable with `status="rejected"`, include a reason, return a non-zero exit code, and must not report `postflight_status="pass"` unless all approved patches were valid and postflight passed. +- Supported target paths: `.prompt` files (excluding `*_LLM.prompt`) and `user_stories/story__*.md`. +- Reject forbidden target paths (e.g., tests, absolute paths, traversal outside the repo root, or files under `pdd/` except `pdd/prompts/**/*.prompt`). +- Supported patch kinds: `vocab_definition`, `contract_rule`, `coverage_line`, `waiver`, `story_template`, `append_covers`, and `full_rewrite`. +- Patch application strategies: + - `full_rewrite` replaces the whole file content. + - `append_covers` appends the replacement to the end of the file. + - Other kinds insert at the specified anchor line, or append to the end of file if not found/invalid. +- For real applies: backup modified files under `.pdd/evidence/checkups/backups//`, write atomically, and run a deterministic postflight checkup. +- In `--dry-run`: do not mutate files or write backups, but log accepted/rejected findings. R1 - Rejected approvals fail honestly -If any approved patch is rejected, `ApplyRunResult.exit_code` MUST be non-zero and `postflight_status` MUST NOT be `pass`. +If any approved patch is rejected, `ApplyRunResult.exit_code` MUST be non-zero and `postflight_status` MUST be `rejected`. -R2 - Prompt source allowlist -`pdd/prompts/**/*.prompt` MAY be repaired, while `pdd/**/*.py`, `tests/**`, generated artifacts, absolute paths, and traversal targets MUST be rejected. +R2 - Target path rules +`.prompt` files (excluding `*_LLM.prompt`) and `user_stories/story__*.md` MAY be repaired, while other paths MUST be rejected. R3 - Dry-run is read-only When `dry_run=True`, no prompt bytes or backup files may be written. From 484b1d6f690af05600841991efe16d07df4032c9 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:35:34 -0700 Subject: [PATCH 23/30] Extend `pdd reconcile` with [BASENAME]/--check/--accept-current/--backfill (part of #1927) - positional [BASENAME] (keep --module as an alias) scopes a run to one unit. - --check: read-only verification with the CI stamper's contract (exit non-zero on any missing/stale/no-code unit; waived+ignored excluded). - --accept-current: stamp CONFLICT units only (explicit human acceptance of the current tree as the agreed baseline). - --backfill: stamp UNBASELINED units only (missing/invalid fingerprint). - --heal keeps stamping single-sided drift; each stamping flag is scoped to exactly its class (_stampable_now now gates drift on --heal). - --json carries the issue #884 verdict shape already produced by the core. Co-Authored-By: Claude --- pdd/commands/reconcile.py | 92 +++++++++++++++++++++++++++++++++++---- pdd/continuous_sync.py | 14 +++--- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/pdd/commands/reconcile.py b/pdd/commands/reconcile.py index 0eb95ff6d4..8965ab4760 100644 --- a/pdd/commands/reconcile.py +++ b/pdd/commands/reconcile.py @@ -10,7 +10,7 @@ import click -from ..continuous_sync import build_report, project_root +from ..continuous_sync import CheckResult, build_report, project_root, run_check def _pre_commit_hook_path(root: Path) -> Path: @@ -49,15 +49,47 @@ def _emit_report(report: dict, as_json: bool) -> None: click.echo(json.dumps(report, indent=2, sort_keys=True)) return summary = report["summary"] + parts = [ + f"metadata_stale={summary['metadata_stale']}", + f"conflicts={summary['conflicts']}", + f"unbaselined={summary['unbaselined']}", + f"failures={summary['failures']}", + ] + if report.get("stamped"): + parts.append(f"stamped={len(report['stamped'])}") + click.echo(" ".join(parts)) + + +def _emit_check(result: CheckResult, as_json: bool) -> None: + """Render a ``--check`` verification result (parity with the CI stamper).""" + if as_json: + payload = { + "ok": result.ok, + "stampable": result.stampable, + "ignored": result.ignored, + "waived": result.waived, + "missing": result.missing, + "stale": [{"basename": b, "fields": f} for b, f in result.stale], + "no_code": result.no_code, + } + click.echo(json.dumps(payload, indent=2, sort_keys=True)) + return click.echo( - f"metadata_stale={summary['metadata_stale']} " - f"conflicts={summary['conflicts']} " - f"unbaselined={summary['unbaselined']} " - f"failures={summary['failures']}" + f"checked {result.stampable} stampable units; " + f"ignored={result.ignored} waived={result.waived}" ) + for name in result.no_code: + click.echo(f" no code file (add a waiver): {name}", err=True) + for name in result.missing: + click.echo(f" missing fingerprint: {name}", err=True) + for name, fields in result.stale: + click.echo(f" stale: {name}: {', '.join(fields)}", err=True) + if result.ok: + click.echo("all fingerprints current") @click.command("reconcile") +@click.argument("basename", required=False) @click.option( "--json", "as_json", @@ -65,6 +97,12 @@ def _emit_report(report: dict, as_json: bool) -> None: default=False, help="Emit machine-readable JSON.", ) +@click.option( + "--check", + is_flag=True, + default=False, + help="Verify fingerprints are current; exit non-zero on drift (no writes).", +) @click.option( "--strict", is_flag=True, @@ -75,7 +113,20 @@ def _emit_report(report: dict, as_json: bool) -> None: "--heal", is_flag=True, default=False, - help="Refresh valid stale fingerprints without LLM calls.", + help="Stamp single-sided drift to the current tree (no LLM, no regen).", +) +@click.option( + "--accept-current", + "accept_current", + is_flag=True, + default=False, + help="Stamp CONFLICT units, accepting the current tree as the agreed baseline.", +) +@click.option( + "--backfill", + is_flag=True, + default=False, + help="Stamp UNBASELINED units (missing/invalid fingerprint) to set a baseline.", ) @click.option( "--ledger", @@ -87,27 +138,50 @@ def _emit_report(report: dict, as_json: bool) -> None: "--module", "module_name", default=None, - help="Limit reconciliation to one module basename.", + help="Alias for the BASENAME argument (limit to one unit).", ) @click.pass_context def reconcile( ctx: click.Context, + basename: Optional[str], as_json: bool, + check: bool, strict: bool, heal: bool, + accept_current: bool, + backfill: bool, ledger: bool, module_name: Optional[str], ) -> None: # pylint: disable=too-many-arguments,too-many-positional-arguments - """Classify and optionally reconcile PDD fingerprint drift.""" + """Classify PDD fingerprint drift and stamp the safe cases (no LLM). + + With no flags, reports each unit's status without writing. ``--heal`` stamps + single-sided drift; ``--accept-current`` additionally stamps CONFLICT units; + ``--backfill`` additionally stamps UNBASELINED units. ``--check`` is a + read-only verification (same contract as the CI stamper) that exits non-zero + on any non-current unit. BASENAME (or ``--module``) limits the run to one unit. + """ ctx.ensure_object(dict) if as_json: ctx.obj["_suppress_result_summary"] = True + target = basename or module_name + modules = [target] if target else None + + if check: + result = run_check(modules=modules) + _emit_check(result, as_json) + if not result.ok: + raise click.exceptions.Exit(1) + return + report = build_report( consumer="reconcile", - modules=[module_name] if module_name else None, + modules=modules, heal=heal, ledger=ledger, + accept_current=accept_current, + backfill=backfill, ) _emit_report(report, as_json) if strict and not report["ok"]: diff --git a/pdd/continuous_sync.py b/pdd/continuous_sync.py index 2bcb69168c..16ebe1f266 100644 --- a/pdd/continuous_sync.py +++ b/pdd/continuous_sync.py @@ -806,15 +806,18 @@ def _append_ledger(root: Path, consumer: str, units: List[Dict[str, Any]]) -> Op return str(ledger_path) if wrote else None -def _stampable_now(classification: str, *, accept_current: bool, backfill: bool) -> bool: +def _stampable_now( + classification: str, *, heal: bool, accept_current: bool, backfill: bool +) -> bool: """Should a unit with this classification be stamped this run? - Single-sided drift is always safe to stamp. CONFLICT (both sides moved) is - stamped only with an explicit ``--accept-current`` (the human declares the - current tree the agreed state); UNBASELINED only with ``--backfill``. + ``heal`` stamps single-sided drift (the safe cases). CONFLICT (both sides + moved) is stamped only with an explicit ``--accept-current`` (the human + declares the current tree the agreed state); UNBASELINED only with + ``--backfill``. Each flag is scoped to exactly its class. """ if classification in DRIFT_CLASSIFICATIONS: - return True + return heal if classification == CONFLICT_CLASSIFICATION: return accept_current if classification == UNBASELINED_CLASSIFICATION: @@ -859,6 +862,7 @@ def build_report( for entry in classified: if _stampable_now( entry["classification"], + heal=heal, accept_current=accept_current, backfill=backfill, ): From fce6cc143fa10ba11320eaf99256ebd3745b3e03 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:39:26 -0700 Subject: [PATCH 24/30] Decouple pdd resolve from continuous_sync (file-boundary #1927) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the team-lead boundary note, continuous_sync.py and commands/reconcile.py are owned by the sibling #1927 effort this wave. Rework pdd resolve so it no longer imports them: classification now reuses sync_determine_operation's own _changed_artifacts_from_hashes (keeping the CONFLICT definition — prompt-side AND derived-side both moved vs the stored fingerprint — identical to the sync decision path), and stamping uses the shared runtime save_fingerprint writer directly. Tests likewise drop the continuous_sync import and assert via the command's own --json output (before/after) plus fingerprint inspection. Behavior and CLI surface unchanged; 8 resolve tests green, pylint 10/10, both gates green. Any overlap with reconcile --accept-current is left for merge-time consolidation. Co-Authored-By: Claude --- pdd/commands/resolve.py | 141 +++++++++++++++++++++------------- tests/test_resolve_command.py | 16 ++-- 2 files changed, 95 insertions(+), 62 deletions(-) diff --git a/pdd/commands/resolve.py b/pdd/commands/resolve.py index ea2db8a5cb..cb67c4c6c1 100644 --- a/pdd/commands/resolve.py +++ b/pdd/commands/resolve.py @@ -12,88 +12,120 @@ strategies (regenerate code from the prompt / back-propagate code into the prompt). These are not yet automated; they print what WOULD run and exit non-zero. + +Deliberately self-contained: classification reuses ``sync_determine_operation``'s +own changed-artifact primitive (so the CONFLICT definition — prompt-side AND +derived-side both moved vs the stored fingerprint — matches the sync decision +path exactly), and stamping uses the shared runtime ``save_fingerprint`` writer. +It does NOT depend on ``continuous_sync``/``reconcile`` (owned by the sibling +#1927 effort); any overlap with ``reconcile --accept-current`` is consolidated at +merge. """ from __future__ import annotations import json -from typing import Dict, Optional +from pathlib import Path +from typing import Dict, List, Optional, Tuple import click -from ..continuous_sync import SyncUnit, classify_unit, discover_units, project_root -from ..operation_log import save_fingerprint -from ..sync_determine_operation import get_pdd_file_paths, read_fingerprint +from ..operation_log import get_fingerprint_path, save_fingerprint +from ..sync_determine_operation import ( + Fingerprint, + _changed_artifacts_from_hashes, + calculate_current_hashes, + get_pdd_file_paths, + read_fingerprint, +) # Fingerprint commands treated as "settled" workflow states. Preserving one of # these (rather than resetting to a running op) keeps a stamped baseline from -# re-triggering verify/test on the next sync — mirrors continuous_sync._heal_units. +# re-triggering verify/test on the next sync. _SETTLED_COMMANDS = {"verify", "test", "fix", "update"} -def _find_unit(basename: str, language: str) -> Optional[SyncUnit]: - """Locate the discovered sync unit for ``basename``/``language`` (or None).""" - base = project_root() - for unit in discover_units(base, modules=[basename]): - if unit.language == language and unit.basename == basename: - return unit - # Fall back to a language-only match (basename may be path-qualified/aliased). - for unit in discover_units(base, modules=[basename]): - if unit.language == language: - return unit - return None - +def _resolve_paths(basename: str, language: str) -> Optional[Dict[str, Path]]: + """Resolve the unit's artifact paths (or None if resolution fails).""" + try: + return get_pdd_file_paths(basename, language, prompts_dir="prompts") + except Exception: # pylint: disable=broad-except + return None -def _baseline_command(basename: str, language: str, paths: Dict) -> str: - """Command to record on the accepted baseline fingerprint.""" - fingerprint = read_fingerprint(basename, language, paths=paths) - if fingerprint and fingerprint.command in _SETTLED_COMMANDS: - return fingerprint.command - return "fix" +def _classify( + basename: str, + language: str, + paths: Dict[str, Path], +) -> Tuple[Optional[Fingerprint], List[str], str]: + """Classify the unit against its stored fingerprint without mutating anything. -def _accept_current(unit: SyncUnit, as_json: bool, quiet: bool) -> int: - """Stamp the current tree as the agreed baseline for ``unit``. + Returns ``(fingerprint, changed_artifacts, classification)``. CONFLICT means + the prompt AND at least one derived artifact both moved vs the fingerprint — + identical to the both-changed trigger in ``_prompt_derived_conflict_decision``. + """ + fingerprint = read_fingerprint(basename, language, paths=paths) + if fingerprint is None: + return None, [], "UNBASELINED" + current = calculate_current_hashes(paths, stored_include_deps=fingerprint.include_deps) + changes = _changed_artifacts_from_hashes(fingerprint, paths, current) + derived = [item for item in changes if item != "prompt"] + if not changes: + classification = "IN_SYNC" + elif "prompt" in changes and derived: + classification = "CONFLICT" + else: + classification = "DRIFT" + return fingerprint, changes, classification + + +def _accept_current( + basename: str, + language: str, + paths: Dict[str, Path], + as_json: bool, + quiet: bool, +) -> int: + """Stamp the current tree as the agreed baseline for the unit. - Transactional at the command level: it re-fingerprints, then re-classifies - and only reports success when the unit lands IN_SYNC. Any other post-state is + Transactional at the command level: it re-fingerprints, then re-classifies and + only reports success when the unit lands IN_SYNC. Any other post-state is surfaced as a failure rather than a silent partial stamp. """ - base = project_root() - before = classify_unit(unit, base) - paths = get_pdd_file_paths( - unit.basename, unit.language, prompts_dir=str(unit.prompts_dir) + before_fp, before_changes, before_class = _classify(basename, language, paths) + command = ( + before_fp.command + if before_fp is not None and before_fp.command in _SETTLED_COMMANDS + else "fix" ) - command = _baseline_command(unit.basename, unit.language, paths) - save_fingerprint(unit.basename, unit.language, command, paths, 0.0, "resolve") - after = classify_unit(unit, base) + save_fingerprint(basename, language, command, paths, 0.0, "resolve") + _after_fp, _after_changes, after_class = _classify(basename, language, paths) - resolved = after["classification"] == "IN_SYNC" + resolved = after_class == "IN_SYNC" result = { - "basename": unit.basename, - "language": unit.language, + "basename": basename, + "language": language, "strategy": "accept-current", - "before": before["classification"], - "after": after["classification"], - "changed_files": before.get("changed_files", []), - "fingerprint_path": after.get("fingerprint_path"), + "before": before_class, + "after": after_class, + "changed_files": before_changes, + "fingerprint_path": str(get_fingerprint_path(basename, language, paths=paths)), "resolved": resolved, } if as_json: click.echo(json.dumps(result, indent=2, sort_keys=True)) elif not quiet: if resolved: - moved = ", ".join(before.get("changed_files", [])) or "no tracked" + moved = ", ".join(before_changes) or "no tracked" click.echo( - f"Resolved '{unit.basename}' ({unit.language}) with --accept-current: " + f"Resolved '{basename}' ({language}) with --accept-current: " f"stamped the current tree as the new baseline " - f"(was {before['classification']}: {moved} changed)." + f"(was {before_class}: {moved} changed)." ) else: click.echo( - f"Could not fully resolve '{unit.basename}' ({unit.language}): " - f"after stamping it is {after['classification']}, not IN_SYNC. " - f"Ensure the prompt and its derived artifacts all exist on disk, " - f"then retry." + f"Could not fully resolve '{basename}' ({language}): after stamping " + f"it is {after_class}, not IN_SYNC. Ensure the prompt and its derived " + f"artifacts all exist on disk, then retry." ) return 0 if resolved else 1 @@ -200,10 +232,15 @@ def resolve( _preview_llm_strategy(basename, language, "code-wins") ) - unit = _find_unit(basename, language) - if unit is None: + paths = _resolve_paths(basename, language) + if paths is None or ( + read_fingerprint(basename, language, paths=paths) is None + and not paths["prompt"].exists() + ): raise click.ClickException( f"No PDD unit '{basename}' ({language}) found to resolve. " - f"Run `pdd sync` or `pdd reconcile` to see tracked units." + f"Run `pdd sync` to see tracked units." ) - raise click.exceptions.Exit(_accept_current(unit, as_json, quiet)) + raise click.exceptions.Exit( + _accept_current(basename, language, paths, as_json, quiet) + ) diff --git a/tests/test_resolve_command.py b/tests/test_resolve_command.py index d65d67e9df..b5b01825ce 100644 --- a/tests/test_resolve_command.py +++ b/tests/test_resolve_command.py @@ -18,7 +18,6 @@ from click.testing import CliRunner -from pdd import continuous_sync as cs from pdd.commands.resolve import resolve from pdd.sync_determine_operation import ( calculate_sha256, @@ -78,24 +77,19 @@ def _make_conflict_unit(base: Path) -> Tuple[str, str, Path]: return BASENAME, LANGUAGE, fp_path -def _classification(base: Path) -> str: - return cs.classify_unit(cs.discover_units(base, modules=[BASENAME])[0], base)[ - "classification" - ] - - def test_accept_current_resolves_conflict_to_in_sync(): runner = CliRunner() with runner.isolated_filesystem() as tmp: base = Path(tmp) _make_conflict_unit(base) - assert _classification(base) == "CONFLICT" result = runner.invoke(resolve, [BASENAME, "--accept-current"], obj={}) assert result.exit_code == 0, result.output - assert _classification(base) == "IN_SYNC" assert "Resolved 'widget'" in result.output + # Idempotent: a second accept-current now sees the unit already IN_SYNC. + again = runner.invoke(resolve, [BASENAME, "--accept-current", "--json"], obj={}) + assert json.loads(again.output)["before"] == "IN_SYNC" def test_accept_current_stamps_the_current_tree_not_the_old_baseline(): @@ -170,7 +164,9 @@ def test_stub_previews_do_not_mutate_the_fingerprint(): runner.invoke(resolve, [BASENAME, "--prompt-wins"], obj={}) assert fp_path.read_text(encoding="utf-8") == before - assert _classification(base) == "CONFLICT" + # Still a conflict after a no-op preview (probed via the command itself). + probe = runner.invoke(resolve, [BASENAME, "--accept-current", "--json"], obj={}) + assert json.loads(probe.output)["before"] == "CONFLICT" def test_requires_exactly_one_strategy(): From e96345276fea4683dd8e99ed1cc49599f5b0bcb0 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:42:20 -0700 Subject: [PATCH 25/30] Make stamp_fingerprints.py a thin wrapper over continuous_sync (part of #1927) The stamper no longer vendors a stdlib copy of pdd's hashing; it imports the shared core (resolve_units / hashes_for / stamp_units / run_check) so the CI gate and `pdd reconcile` can never diverge. The CLI contract is unchanged: `--check` prints the same "checked N stampable units..." lines and the same exit codes CI depends on, and the default stamp is now idempotent (unchanged units are skipped). Adds a small public API to continuous_sync (resolve_unit/resolve_units/ hashes_for/stamp_units) so the wrapper needs no protected-member access. test_stamper_is_stdlib_only is inverted into test_stamper_delegates_to_ continuous_sync: the stdlib-only invariant is intentionally lifted (the team lead's call: CI installs the package), and the new test guards that the script imports the shared core and re-vendors no hashlib hashing. The other 15 stamper tests pass unchanged. `stamp_fingerprints.py --check` stays green (223 current). Co-Authored-By: Claude --- pdd/continuous_sync.py | 45 +- scripts/stamp_fingerprints.py | 681 ++++--------------------------- tests/test_stamp_fingerprints.py | 18 +- 3 files changed, 141 insertions(+), 603 deletions(-) diff --git a/pdd/continuous_sync.py b/pdd/continuous_sync.py index 16ebe1f266..20fa6cda55 100644 --- a/pdd/continuous_sync.py +++ b/pdd/continuous_sync.py @@ -25,6 +25,7 @@ error). Machine-readable verdicts additionally carry the issue #884 shape (``status`` / ``reasons`` / ``affected_artifacts`` / ``remediation``). """ +# pylint: disable=too-many-lines from __future__ import annotations import contextlib @@ -395,6 +396,27 @@ def _unit_wanted(basename: str, prompt: Path, wanted: set) -> bool: ) +def resolve_units( + root: Path, modules: Optional[Iterable[str]] = None +) -> List[Unit]: + """Public: resolve every python unit under ``root`` (stamper-parity paths).""" + layout = _layout_for(Path(root)) + arch_maps = _load_architecture(layout.architecture_file) + return enumerate_units(layout, arch_maps, modules=modules) + + +def resolve_unit(basename: str, root: Path, prompt: Optional[Path] = None) -> Unit: + """Public: resolve one unit's artifact paths against ``root``. + + ``prompt`` defaults to ``/_python.prompt``. + """ + layout = _layout_for(Path(root)) + arch_maps = _load_architecture(layout.architecture_file) + if prompt is None: + prompt = layout.prompts_root / f"{basename}{PROMPT_SUFFIX}" + return _build_unit(basename, Path(prompt), layout, arch_maps) + + # --- .pddignore & waivers ---------------------------------------------------- @@ -494,13 +516,21 @@ def compute_current_hashes( """Recompute all fingerprint hash fields for ``unit`` via pdd's real hasher. Must run under ``_chdir(root)`` so resolution matches the committed - fingerprints. + fingerprints (see the public ``hashes_for`` for a self-contained variant). """ return calculate_current_hashes( _paths_for_hashing(unit), stored_include_deps=stored_deps ) +def hashes_for( + unit: Unit, root: Path, stored_deps: Optional[Dict[str, str]] = None +) -> Dict[str, Any]: + """Public: recompute ``unit``'s hashes with cwd anchored at ``root``.""" + with _chdir(Path(root)): + return compute_current_hashes(unit, stored_deps) + + def _read_fingerprint_obj(unit: Unit) -> Optional[Fingerprint]: """Read ``unit``'s committed fingerprint, or None if missing/invalid. @@ -759,6 +789,19 @@ def stamp_unit(unit: Unit) -> bool: return True +def stamp_units(units: Iterable[Unit], root: Path) -> List[str]: + """Public: idempotently stamp each unit with cwd anchored at ``root``. + + Returns the basenames actually written (unchanged units are skipped). + """ + written: List[str] = [] + with _chdir(Path(root)): + for unit in units: + if stamp_unit(unit): + written.append(unit.basename) + return written + + # --- Reporting --------------------------------------------------------------- diff --git a/scripts/stamp_fingerprints.py b/scripts/stamp_fingerprints.py index 72e8218048..874b8c6e01 100644 --- a/scripts/stamp_fingerprints.py +++ b/scripts/stamp_fingerprints.py @@ -1,482 +1,87 @@ #!/usr/bin/env python3 -"""Stamp / verify ``.pdd/meta`` fingerprints for every PDD dev unit (stdlib only). - -The committed ``.pdd/meta/.json`` fingerprints are the oracle ``pdd sync`` -trusts to decide whether a unit changed. When they are missing or stale, sync -diffs current files against absent/old hashes, sees phantom "changed" verdicts, -and regenerates mature modules (issue #1938). This script keeps that oracle -current for the whole tree: - -* ``stamp`` (default): for every unit, recompute all hashes from the files on - disk and write the fingerprint JSON, byte-identically to how ``pdd`` writes - it (``pdd/sync_orchestration.py`` ``_atomic_write`` / ``operation_log.save_fingerprint`` - -> ``json.dump(..., indent=2)`` with no trailing newline, ``Fingerprint`` - dataclass key order). Existing units keep their ``command``; new units get a - neutral ``command`` (see ``NEW_UNIT_COMMAND``). - -* ``--check``: recompute every unit's hashes and compare to the committed - fingerprint. Exit non-zero listing units whose stored hashes are stale (drift - or a hand-edit) or that have no committed fingerprint and are not waived. This - is the primitive the CI gate reuses. - -Stdlib only, no ``pdd`` import, no LLM: the hashing is vendored verbatim from -``pdd/sync_determine_operation.py`` (pinned byte-for-byte by the cross-check in -``tests/test_stamp_fingerprints.py``). Path resolution mirrors the repo's -``.pddrc`` convention: a prompt at ``pdd/prompts//_python.prompt`` -maps to code ``pdd//.py``, example ``context//_example.py``, -tests ``tests//test_*.py``. - -Never hand-edit ``.pdd/meta``; regenerate via this stamper (see CONTRIBUTING.md). +"""Stamp / verify ``.pdd/meta`` fingerprints for every PDD dev unit. + +Thin wrapper over ``pdd.continuous_sync`` (issue #1927: one implementation shared +with ``pdd reconcile``). The committed ``.pdd/meta/.json`` fingerprints are +the oracle ``pdd sync`` trusts to decide whether a unit changed; this script keeps +that oracle current for the whole tree and verifies it in CI: + +* ``stamp`` (default): for every stampable unit, recompute all hashes from the + files on disk and write the fingerprint JSON byte-identically to how ``pdd`` + writes it. Idempotent — a unit whose content hashes already match is not + rewritten (its timestamp is preserved and no file is written), so a repo-wide + restamp touches only genuinely-changed units. + +* ``--check``: recompute every stampable unit's hashes and compare to the committed + fingerprint; exit non-zero listing units that are stale or missing a fingerprint. + This is the CI gate (``.github/workflows/unit-tests.yml``); its output shape and + exit codes are unchanged. + +Hashing and unit/path resolution live in ``pdd.continuous_sync`` and use pdd's real +hash functions, so a fingerprint this script writes equals what ``pdd sync`` would +compute. Historically this file vendored a stdlib-only copy of pdd's hashing to run +without importing pdd; issue #1927 removed that second implementation, so the +script now imports pdd (CI installs the package before running the gate). """ from __future__ import annotations import argparse -import fnmatch -import glob -import hashlib import json -import os -import re -import subprocess import sys -from datetime import datetime, timezone from pathlib import Path -from typing import Dict, List, Optional, Tuple - -# --- Repo layout ------------------------------------------------------------- +from typing import Dict, List, Optional +# Ensure the repo root is importable when run as ``scripts/stamp_fingerprints.py`` +# (CI also ``pip install -e``s the package, but this keeps a bare checkout working). REPO_ROOT = Path(__file__).resolve().parent.parent +if str(REPO_ROOT) not in sys.path: + sys.path.insert(0, str(REPO_ROOT)) + +from pdd import continuous_sync as _cs # pylint: disable=wrong-import-position,no-name-in-module + +# Re-exported for callers/tests that imported these from the stamper. PROMPTS_ROOT = REPO_ROOT / "pdd" / "prompts" META_DIR = REPO_ROOT / ".pdd" / "meta" WAIVERS_FILE = REPO_ROOT / "scripts" / "fingerprint_waivers.json" -ARCHITECTURE_FILE = REPO_ROOT / "architecture.json" - -LANGUAGE = "python" -PROMPT_SUFFIX = "_python.prompt" - -# The ``command`` recorded for a freshly-created fingerprint. ``pdd sync``'s -# completion gate (sync_determine_operation.py: COMPLETED_VERIFY_COMMANDS / -# COMPLETED_TEST_COMMANDS = {'verify','test','fix','update'} / {'test','fix', -# 'update'}) treats a unit as "workflow complete" -> nothing to do only when the -# command is in {test, fix, update}. 'fix' is chosen because it satisfies both -# gates, triggers none of the special branches ('auto-deps' forces generate, -# 'crash' forces a retry, a 'skip:' prefix means skipped), and is already the -# modal command among committed fingerprints. The epoch stamp declares the -# current tree the agreed baseline, so a terminal at-rest command is truthful. -NEW_UNIT_COMMAND = "fix" - -# Fingerprint dataclass field order (pdd/sync_determine_operation.py Fingerprint). -# Written key order MUST match so a subsequent `pdd sync` produces no spurious diff. -FIELD_ORDER = ( - "pdd_version", - "timestamp", - "command", - "prompt_hash", - "code_hash", - "example_hash", - "test_hash", - "test_files", - "include_deps", -) - -# Hash fields --check recomputes and compares (metadata fields pdd_version / -# timestamp / command are not content-derived and are not checked). -HASH_FIELDS = ( - "prompt_hash", - "code_hash", - "example_hash", - "test_hash", - "test_files", - "include_deps", -) - - -# --- BEGIN verbatim copies from pdd/pdd/sync_determine_operation.py ----------- -# Keep byte-for-byte identical to pdd so recomputed hashes match the CLI. Pinned -# by tests/test_stamp_fingerprints.py::test_hash_parity_with_pdd. - -_INCLUDE_PATTERN = re.compile(r"]*>(.*?)") -_BACKTICK_INCLUDE_PATTERN = re.compile(r"```<([^>]*?)>```") - - -def calculate_sha256(file_path: Path) -> Optional[str]: - """Calculates the SHA256 hash of a file if it exists.""" - if not file_path.exists(): - return None - - try: - hasher = hashlib.sha256() - with open(file_path, "rb") as f: - for chunk in iter(lambda: f.read(4096), b""): - hasher.update(chunk) - return hasher.hexdigest() - except (IOError, OSError): - return None - - -def _resolve_include_path(include_ref: str, prompt_dir: Path) -> Optional[Path]: - """Resolve an reference to an absolute Path.""" - p = Path(include_ref) - if p.is_absolute() and p.exists(): - return p - candidate = prompt_dir / include_ref - if candidate.exists(): - return candidate - candidate = Path.cwd() / include_ref - if candidate.exists(): - return candidate - return None - - -def extract_include_deps(prompt_path: Path) -> Dict[str, str]: - """Extract include dependency paths and their hashes from a prompt file. - - Returns a dict mapping resolved dependency paths to their SHA256 hashes. - Only includes dependencies that exist on disk. - """ - if not prompt_path.exists(): - return {} - - try: - prompt_content = prompt_path.read_text(encoding="utf-8", errors="ignore") - except (IOError, OSError): - return {} - - include_refs = _INCLUDE_PATTERN.findall(prompt_content) - include_refs += _BACKTICK_INCLUDE_PATTERN.findall(prompt_content) - - if not include_refs: - return {} - - deps = {} - prompt_dir = prompt_path.parent - for ref in sorted(set(r.strip() for r in include_refs)): - dep_path = _resolve_include_path(ref, prompt_dir) - if dep_path and dep_path.exists(): - dep_hash = calculate_sha256(dep_path) - if dep_hash: - try: - rel_path = dep_path.relative_to(Path.cwd()) - except ValueError: - rel_path = dep_path - deps[str(rel_path)] = dep_hash - - return deps - - -def calculate_prompt_hash( - prompt_path: Path, stored_deps: Optional[Dict[str, str]] = None -) -> Optional[str]: - """Hash a prompt file including the content of all its dependencies. - - If the prompt has tags, extracts and hashes those dependencies. - If no tags are found but stored_deps is provided (from a previous fingerprint), - uses those stored dependency paths to compute the hash. This handles the case - where the auto-deps step strips tags from the prompt file. - """ - if not prompt_path.exists(): - return None - - try: - prompt_content = prompt_path.read_text(encoding="utf-8", errors="ignore") - except (IOError, OSError): - return None - - # Try to find include refs in current prompt content - include_refs = _INCLUDE_PATTERN.findall(prompt_content) - include_refs += _BACKTICK_INCLUDE_PATTERN.findall(prompt_content) - - # Resolve to actual paths - prompt_dir = prompt_path.parent - dep_paths = [] - if include_refs: - for ref in sorted(set(r.strip() for r in include_refs)): - dep_path = _resolve_include_path(ref, prompt_dir) - if dep_path and dep_path.exists(): - dep_paths.append(dep_path) - elif stored_deps: - # No include tags in prompt - use stored dependency paths from fingerprint - for dep_path_str in sorted(stored_deps.keys()): - dep_path = Path(dep_path_str) - if dep_path.exists(): - dep_paths.append(dep_path) - - if not dep_paths: - return calculate_sha256(prompt_path) - - # Build composite hash: prompt bytes + sorted dependency contents - hasher = hashlib.sha256() - try: - with open(prompt_path, "rb") as f: - for chunk in iter(lambda: f.read(4096), b""): - hasher.update(chunk) - except (IOError, OSError): - return None - - for dep_path in dep_paths: - try: - with open(dep_path, "rb") as f: - for chunk in iter(lambda: f.read(4096), b""): - hasher.update(chunk) - except (IOError, OSError): - pass - - return hasher.hexdigest() - - -# --- END verbatim copies ----------------------------------------------------- +FIELD_ORDER = _cs.FIELD_ORDER +HASH_FIELDS = _cs.HASH_FIELDS +NEW_UNIT_COMMAND = _cs.NEW_UNIT_COMMAND -def refresh_include_deps( - prompt_path: Path, stored_deps: Optional[Dict[str, str]] = None -) -> Dict[str, str]: - """Recompute ``include_deps`` mirroring pdd's ``calculate_current_hashes``. +# --- Resolution / enumeration (delegated to pdd.continuous_sync) -------------- - Ports the prompt branch of ``sync_determine_operation.calculate_current_hashes``: - extract fresh deps from the prompt's tags; if the prompt no longer - has tags but stored deps exist (auto-deps stripped, issue #522), re-hash the - stored dependency keys. - """ - deps = extract_include_deps(prompt_path) - if not deps and stored_deps: - updated_deps: Dict[str, str] = {} - for dep_path_str, _old_hash in stored_deps.items(): - dep_path = Path(dep_path_str) - if dep_path.exists(): - new_hash = calculate_sha256(dep_path) - if new_hash: - updated_deps[dep_path_str] = new_hash - deps = updated_deps - return deps - - -def _safe_basename(basename: str) -> str: - """Sanitize basename for use in metadata filenames ('/' -> '_').""" - return basename.replace("/", "_") - - -# --- architecture.json resolution -------------------------------------------- -# pdd's get_pdd_file_paths consults architecture.json FIRST for a module's code -# filepath (issue #225), and disambiguates example/test stems for a bare leaf -# that maps to more than one module (issue #1677). Both are pure JSON+path logic -# (no LLM), so they are mirrored here. For the ~99% of units whose architecture -# filepath equals the .pddrc convention pdd/.py, this changes nothing; -# it corrects the handful whose code lives outside the prompt's subdir (e.g. -# commands/checkup_simplify -> pdd/checkup_simplify.py) and the ambiguous leaves -# cli/gate. - - -def _load_architecture(): - """Return ``(by_filename, by_leaf, ambiguous_leaves)`` from architecture.json. - - * ``by_filename``: full architecture filename (lower) -> set of filepaths. - Architecture filenames are frequently path-qualified (``core/cli_python.prompt``). - * ``by_leaf``: filename leaf (lower) -> set of filepaths. - * ``ambiguous_leaves``: basenames whose bare leaf maps to >1 distinct filepath - (mirrors ``_architecture_module_choices``; these get a disambiguated stem). - """ - by_filename: Dict[str, set] = {} - by_leaf: Dict[str, set] = {} - if not ARCHITECTURE_FILE.is_file(): - return by_filename, by_leaf, frozenset() - try: - data = json.loads(ARCHITECTURE_FILE.read_text(encoding="utf-8")) - except (OSError, json.JSONDecodeError): - return by_filename, by_leaf, frozenset() - modules = data if isinstance(data, list) else data.get("modules", []) if isinstance(data, dict) else [] - for module in modules: - if not isinstance(module, dict): - continue - filename = str(module.get("filename") or "").strip() - filepath = str(module.get("filepath") or "").strip() - if not filename or not filepath or filename.endswith("_LLM.prompt"): - continue - fp = Path(filepath).as_posix() - by_filename.setdefault(filename.lower(), set()).add(fp) - by_leaf.setdefault(Path(filename).name.lower(), set()).add(fp) - ambiguous = frozenset( - leaf[: -len(f"_{LANGUAGE}.prompt")] - for leaf, fps in by_leaf.items() - if leaf.endswith(f"_{LANGUAGE}.prompt") and len(fps) > 1 - ) - return by_filename, by_leaf, ambiguous +def Unit(basename: str, prompt: Optional[Path] = None): # pylint: disable=invalid-name + """Resolve one unit against the repo layout (compat shim for the stamper API). -_ARCH_BY_FILENAME, _ARCH_BY_LEAF, _AMBIGUOUS_LEAVES = _load_architecture() - - -def _resolve_code_and_stem(basename: str) -> Tuple[Path, str]: - """Return ``(code_path, artifact_stem)`` mirroring pdd's resolution. - - ``code_path`` is the architecture.json filepath when the prompt is listed - there, else the ``pdd/.py`` convention. ``artifact_stem`` is the - stem used for the example/test filenames: the code file's stem, replaced by - a ``_safe_basename()`` disambiguation when the bare leaf - is ambiguous (issue #1677). - """ - leaf = basename.rsplit("/", 1)[-1] - pf_full = f"{basename}_{LANGUAGE}.prompt".lower() - pf_leaf = f"{leaf}_{LANGUAGE}.prompt".lower() - - arch_fp: Optional[str] = None - full_fps = _ARCH_BY_FILENAME.get(pf_full) - if full_fps and len(full_fps) == 1: - arch_fp = next(iter(full_fps)) - if arch_fp is None: - leaf_fps = _ARCH_BY_LEAF.get(pf_leaf, set()) - if len(leaf_fps) == 1: - arch_fp = next(iter(leaf_fps)) - elif len(leaf_fps) > 1: - # Ambiguous bare leaf: accept only if exactly one filepath aligns - # with the path-qualified basename (flat ambiguous units are waived). - aligned = [ - fp for fp in leaf_fps - if Path(fp).with_suffix("").as_posix().endswith(basename) - ] - if len(aligned) == 1: - arch_fp = aligned[0] - - if arch_fp: - code = REPO_ROOT / arch_fp - if leaf in _AMBIGUOUS_LEAVES: - stem = _safe_basename(Path(arch_fp).with_suffix("").as_posix()) - else: - stem = Path(arch_fp).stem - else: - code = REPO_ROOT / "pdd" / f"{basename}.py" - stem = leaf - return code, stem - - -# --- Unit enumeration & path resolution -------------------------------------- - - -class Unit: - """A single PDD dev unit resolved from a ``*_python.prompt`` file.""" - - __slots__ = ("basename", "prompt", "code", "example", "test", "test_files", "meta") - - def __init__(self, basename: str, prompt: Path) -> None: - self.basename = basename - self.prompt = prompt - # Code path + artifact stem come from architecture.json (falling back to - # the pdd/.py convention); the example/test DIRECTORY follows - # the prompt's subdir (context/, tests/), mirroring pdd. - subdir = str(Path(basename).parent) if "/" in basename else "" - self.code, stem = _resolve_code_and_stem(basename) - example_dir = REPO_ROOT / "context" / subdir if subdir else REPO_ROOT / "context" - self.example = example_dir / f"{stem}_example.py" - test_dir = REPO_ROOT / "tests" / subdir if subdir else REPO_ROOT / "tests" - self.test = test_dir / f"test_{stem}.py" - self.test_files = _discover_test_files(test_dir, stem) - self.meta = META_DIR / f"{_safe_basename(basename)}_{LANGUAGE}.json" - - -def _discover_test_files(test_dir: Path, stem: str) -> List[Path]: - """Mirror pdd's Bug #156 test-file globbing: sorted ``test_*.py``. - - Matches ``get_pdd_file_paths``: glob ``test_*.py`` in the test dir, - falling back to the single primary test path when the dir or matches are - absent. + ``prompt`` defaults to the conventional ``pdd/prompts/_python.prompt``. """ - primary = test_dir / f"test_{stem}.py" - if test_dir.is_dir(): - pattern = glob.escape(f"test_{stem}") - matches = sorted(test_dir.glob(f"{pattern}*.py")) - else: - matches = [primary] if primary.exists() else [] - return matches or [primary] + return _cs.resolve_unit(basename, REPO_ROOT, prompt) -def infer_basename(prompt_path: Path) -> Optional[str]: - """Return the unit basename for a ``*_python.prompt`` file, or None. - - Basename is the path relative to ``pdd/prompts`` with the ``_python.prompt`` - suffix dropped, subdirectories preserved (e.g. ``commands/which``). - """ - name = prompt_path.name - if not name.endswith(PROMPT_SUFFIX): - return None - rel = prompt_path.relative_to(PROMPTS_ROOT) - stem = rel.name[: -len(PROMPT_SUFFIX)] - subdir = rel.parent - if str(subdir) == ".": - return stem - return (subdir / stem).as_posix() - - -def enumerate_units() -> List[Unit]: +def enumerate_units(): """Return every python unit under ``pdd/prompts`` sorted by basename.""" - units: List[Unit] = [] - for prompt in sorted(PROMPTS_ROOT.rglob(f"*{PROMPT_SUFFIX}")): - basename = infer_basename(prompt) - if basename is None: - continue - units.append(Unit(basename, prompt)) - return units - - -# --- .pddignore -------------------------------------------------------------- + return _cs.resolve_units(REPO_ROOT) def load_pddignore() -> List[str]: - """Load ``.pddignore`` patterns from the repo root (comments/blank stripped).""" - path = REPO_ROOT / ".pddignore" - patterns: List[str] = [] - if not path.is_file(): - return patterns - for line in path.read_text(encoding="utf-8").splitlines(): - line = line.strip() - if not line or line.startswith("#"): - continue - patterns.append(line) - return patterns - - -def is_pddignored(code_path: Path, patterns: List[str]) -> bool: - """Mirror pdd/update_main.py ``_is_pddignored`` against the code path. - - Matches the repo-relative POSIX path and the basename via fnmatch, plus - directory-prefix patterns ending in '/'. - """ - try: - rel_path = code_path.resolve().relative_to(REPO_ROOT).as_posix() - except ValueError: - return False - basename = code_path.name - for pat in patterns: - if pat.endswith("/"): - dir_name = pat.rstrip("/") - parts = rel_path.split("/") - if dir_name in parts[:-1]: - return True - else: - if fnmatch.fnmatch(rel_path, pat): - return True - if fnmatch.fnmatch(basename, pat): - return True - return False - - -# --- Waivers ----------------------------------------------------------------- + """Load ``.pddignore`` patterns from the repo root.""" + return _cs.load_pddignore(REPO_ROOT) def load_waivers() -> Dict[str, str]: """Return ``{basename: reason}`` from the committed waiver file.""" - if not WAIVERS_FILE.is_file(): - return {} - data = json.loads(WAIVERS_FILE.read_text(encoding="utf-8")) - waivers: Dict[str, str] = {} - for entry in data.get("waivers", []): - waivers[entry["basename"]] = entry.get("reason", "") - return waivers + return _cs.load_waivers(WAIVERS_FILE) -# --- Meta read / write ------------------------------------------------------- +def classify(units, pddignore, waivers): + """Split units into ``(stampable, ignored, waived, no_code)`` buckets.""" + return _cs.partition_units(units, pddignore, waivers, REPO_ROOT) def read_meta(meta_path: Path) -> Optional[Dict]: """Read an existing fingerprint JSON, or None if absent/unreadable.""" + meta_path = Path(meta_path) if not meta_path.exists(): return None try: @@ -486,199 +91,81 @@ def read_meta(meta_path: Path) -> Optional[Dict]: return data if isinstance(data, dict) else None -def compute_hashes(unit: Unit, stored_deps: Optional[Dict[str, str]]) -> Dict: - """Recompute all fingerprint hash fields for a unit from disk. - - Mirrors ``calculate_current_hashes``: composite ``prompt_hash`` (with stored - deps fallback), per-file sha256, and the Bug #156 ``test_files`` map. - """ - test_files = { - f.name: calculate_sha256(f) for f in unit.test_files if f.exists() - } - return { - "prompt_hash": calculate_prompt_hash(unit.prompt, stored_deps=stored_deps), - "code_hash": calculate_sha256(unit.code), - "example_hash": calculate_sha256(unit.example), - "test_hash": calculate_sha256(unit.test), - "test_files": test_files, - "include_deps": refresh_include_deps(unit.prompt, stored_deps), - } - - -def build_fingerprint(unit: Unit, pdd_version: str) -> Dict: - """Build the full fingerprint dict for a unit (preserving prior command).""" - existing = read_meta(unit.meta) - stored_deps = None - command = NEW_UNIT_COMMAND - if existing is not None: - sd = existing.get("include_deps") - stored_deps = sd if isinstance(sd, dict) else None - if existing.get("command"): - command = existing["command"] - hashes = compute_hashes(unit, stored_deps) - fingerprint = { - "pdd_version": pdd_version, - "timestamp": datetime.now(timezone.utc).isoformat(), - "command": command, - "prompt_hash": hashes["prompt_hash"], - "code_hash": hashes["code_hash"], - "example_hash": hashes["example_hash"], - "test_hash": hashes["test_hash"], - "test_files": hashes["test_files"], - "include_deps": hashes["include_deps"], - } - return {k: fingerprint[k] for k in FIELD_ORDER} +def compute_hashes(unit, stored_deps: Optional[Dict[str, str]] = None) -> Dict: + """Recompute all fingerprint hash fields for a unit via pdd's real hasher.""" + return _cs.hashes_for(unit, REPO_ROOT, stored_deps) def write_meta(meta_path: Path, content: Dict) -> None: """Write meta JSON byte-identically to pdd (indent=2, no trailing newline).""" + meta_path = Path(meta_path) meta_path.parent.mkdir(parents=True, exist_ok=True) with open(meta_path, "w", encoding="utf-8") as handle: json.dump(content, handle, indent=2) -def current_pdd_version() -> str: - """Return the current tree's pdd version (``git describe`` tag, no leading v). - - setuptools_scm generates ``pdd/_version.py`` only at build time, so derive - from git tags for a source checkout. Falls back to '0.0.0' when git tags are - unavailable (the version field is metadata; --check does not compare it). - """ - try: - out = subprocess.run( - ["git", "-C", str(REPO_ROOT), "describe", "--tags", "--abbrev=0"], - capture_output=True, - text=True, - check=False, - ) - tag = (out.stdout or "").strip() - if tag: - return tag[1:] if tag.startswith("v") else tag - except (OSError, subprocess.SubprocessError): - pass - return "0.0.0" - - -# --- Unit classification ----------------------------------------------------- - - -def classify(units: List[Unit], pddignore: List[str], waivers: Dict[str, str]): - """Split units into (stampable, ignored, waived, no_code) buckets. - - * ignored: code path matches ``.pddignore`` (pdd never tracks these). - * waived: basename appears in the committed waiver file. - * no_code: code file absent and not already waived (cannot be hashed). - * stampable: everything else. - """ - stampable: List[Unit] = [] - ignored: List[Unit] = [] - waived: List[Unit] = [] - no_code: List[Unit] = [] - for unit in units: - if is_pddignored(unit.code, pddignore): - ignored.append(unit) - elif unit.basename in waivers: - waived.append(unit) - elif not unit.code.exists(): - no_code.append(unit) - else: - stampable.append(unit) - return stampable, ignored, waived, no_code - - # --- Commands ---------------------------------------------------------------- -def cmd_stamp(args: argparse.Namespace) -> int: - """Recompute and write fingerprints for every stampable unit.""" +def cmd_stamp(_args: argparse.Namespace) -> int: + """Recompute and write fingerprints for every stampable unit (idempotent).""" units = enumerate_units() pddignore = load_pddignore() waivers = load_waivers() stampable, ignored, waived, no_code = classify(units, pddignore, waivers) - pdd_version = current_pdd_version() - prev_cwd = Path.cwd() - os.chdir(REPO_ROOT) # include resolution + dep keys are cwd-relative - written = 0 - try: - for unit in stampable: - fingerprint = build_fingerprint(unit, pdd_version) - write_meta(unit.meta, fingerprint) - written += 1 - finally: - os.chdir(prev_cwd) + written = len(_cs.stamp_units(stampable, REPO_ROOT)) print( - f"stamped {written} units (pdd_version={pdd_version}); " + f"stamped {written} of {len(stampable)} units " + f"(unchanged {len(stampable) - written}); " f"ignored={len(ignored)} waived={len(waived)} no_code={len(no_code)}" ) if no_code: print("WARNING: units with no code file (add to waivers):", file=sys.stderr) for unit in no_code: - print(f" {unit.basename} -> {unit.code.relative_to(REPO_ROOT)}", file=sys.stderr) + print(f" {unit.basename} -> {unit.code}", file=sys.stderr) return 1 return 0 -def cmd_check(args: argparse.Namespace) -> int: +def cmd_check(_args: argparse.Namespace) -> int: """Recompute hashes and diff against committed metas. Non-zero on drift.""" - units = enumerate_units() - pddignore = load_pddignore() - waivers = load_waivers() - stampable, ignored, waived, no_code = classify(units, pddignore, waivers) - - missing: List[str] = [] - stale: List[Tuple[str, List[str]]] = [] - unwaived_no_code: List[str] = [] - - prev_cwd = Path.cwd() - os.chdir(REPO_ROOT) - try: - for unit in no_code: - unwaived_no_code.append(unit.basename) - for unit in stampable: - existing = read_meta(unit.meta) - if existing is None: - missing.append(unit.basename) - continue - sd = existing.get("include_deps") - stored_deps = sd if isinstance(sd, dict) else None - current = compute_hashes(unit, stored_deps) - diffs = [ - field - for field in HASH_FIELDS - if (existing.get(field) or None) != (current.get(field) or None) - ] - if diffs: - stale.append((unit.basename, diffs)) - finally: - os.chdir(prev_cwd) - - ok = not (missing or stale or unwaived_no_code) - total = len(stampable) + result = _cs.run_check() print( - f"checked {total} stampable units; " - f"ignored={len(ignored)} waived={len(waived)}" + f"checked {result.stampable} stampable units; " + f"ignored={result.ignored} waived={result.waived}" ) - if unwaived_no_code: - print(f"\n{len(unwaived_no_code)} unit(s) have no code file and no waiver:", file=sys.stderr) - for name in sorted(unwaived_no_code): + if result.no_code: + print( + f"\n{len(result.no_code)} unit(s) have no code file and no waiver:", + file=sys.stderr, + ) + for name in result.no_code: print(f" {name}", file=sys.stderr) - if missing: - print(f"\n{len(missing)} unit(s) missing a committed fingerprint:", file=sys.stderr) - for name in sorted(missing): + if result.missing: + print( + f"\n{len(result.missing)} unit(s) missing a committed fingerprint:", + file=sys.stderr, + ) + for name in result.missing: print(f" {name}", file=sys.stderr) - if stale: - print(f"\n{len(stale)} unit(s) have stale fingerprints (run: python scripts/stamp_fingerprints.py):", file=sys.stderr) - for name, diffs in sorted(stale): + if result.stale: + print( + f"\n{len(result.stale)} unit(s) have stale fingerprints " + f"(run: python scripts/stamp_fingerprints.py):", + file=sys.stderr, + ) + for name, diffs in result.stale: print(f" {name}: {', '.join(diffs)}", file=sys.stderr) - if ok: + if result.ok: print("all fingerprints current") return 0 return 1 def main(argv: Optional[List[str]] = None) -> int: + """Stamp (default) or verify (``--check``) the repo's ``.pdd/meta`` fingerprints.""" parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) parser.add_argument( "--check", diff --git a/tests/test_stamp_fingerprints.py b/tests/test_stamp_fingerprints.py index 27b733b531..897c52d99c 100644 --- a/tests/test_stamp_fingerprints.py +++ b/tests/test_stamp_fingerprints.py @@ -47,18 +47,26 @@ def _load_stamper(): ] -def test_stamper_is_stdlib_only(): - """The stamper must not import pdd (it runs offline in CI / the nightly runner).""" +def test_stamper_delegates_to_continuous_sync(): + """Issue #1927: the stamper shares pdd.continuous_sync's hashing/resolution. + + It previously vendored a stdlib-only copy of pdd's hash functions so it could + run without importing pdd; #1927 removed that second implementation, so the + script now imports the shared core (CI installs the package before the gate). + Guard that the delegation stays in place and no vendored hashing creeps back. + """ import ast tree = ast.parse(STAMPER_PATH.read_text(encoding="utf-8")) imported = set() for node in ast.walk(tree): if isinstance(node, ast.Import): - imported.update(alias.name.split(".")[0] for alias in node.names) + imported.update(alias.name for alias in node.names) elif isinstance(node, ast.ImportFrom) and node.module: - imported.add(node.module.split(".")[0]) - assert "pdd" not in imported + imported.add(node.module) + assert any(m == "pdd" or m.startswith("pdd.") for m in imported), imported + # Single implementation: the script must not re-vendor hashlib-based hashing. + assert "hashlib" not in imported def test_write_meta_byte_format(tmp_path): From 17dff187e7c0ed9b90da0b8532e381bd2e797025 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 13:48:45 -0700 Subject: [PATCH 26/30] Add continuous_sync tests; retire stale continuous_sync test waiver (part of #1927) tests/test_continuous_sync.py covers the four reconcile verdicts (current / stamped / conflict / unbaselined), the --accept-current (CONFLICT-only) and --backfill (unbaselined-only) stamping scopes, the issue #884 --json verdict shape, idempotency (second run is a no-op; a single changed unit touches only its own fingerprint), the two resolution regressions #1954 got wrong (commands/firecrawl, core/remote_session vs remote_session), the reconcile CLI (--check exit codes, BASENAME + --json), and script<->command parity on the committed tree. Removes the now-satisfied "TODO add tests/test_continuous_sync.py" orphan waiver from architecture_waivers.json. Co-Authored-By: Claude --- architecture_waivers.json | 1 - tests/test_continuous_sync.py | 297 ++++++++++++++++++++++++++++++++++ 2 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 tests/test_continuous_sync.py diff --git a/architecture_waivers.json b/architecture_waivers.json index a3d39362d1..2754c9beab 100644 --- a/architecture_waivers.json +++ b/architecture_waivers.json @@ -91,7 +91,6 @@ "cli_branding": "User-facing branding strings; low-risk constants. TODO add tests/test_cli_branding.py.", "compression_reporting": "context-compression reporting; TODO add tests/test_compression_reporting.py.", "config_resolution": "Centralized config resolution; TODO add tests/test_config_resolution.py.", - "continuous_sync": "continuous-sync classification; TODO add tests/test_continuous_sync.py.", "contract_ir": "Contract authoring IR; TODO add tests/test_contract_ir.py.", "edit_file": "LLM file editor; TODO add tests/test_edit_file.py.", "evidence_store": "Evidence manifest loader; TODO add tests/test_evidence_store.py.", diff --git a/tests/test_continuous_sync.py b/tests/test_continuous_sync.py new file mode 100644 index 0000000000..79a6c95ccd --- /dev/null +++ b/tests/test_continuous_sync.py @@ -0,0 +1,297 @@ +"""Tests for pdd.continuous_sync — the shared reconcile/stamp core (issue #1927). + +Covers the four reconcile verdicts (current / stamped / conflict / unbaselined), +the --accept-current and --backfill stamping scopes, the issue #884 --json verdict +shape, idempotency (second run is a no-op; a single changed unit touches only its +own fingerprint), the two resolution regressions the #1954 command got wrong +(commands/firecrawl, core/remote_session vs remote_session), and script<->command +parity on the committed tree. +""" +import importlib.util +import json +from pathlib import Path + +import pytest +from click.testing import CliRunner + +from pdd import continuous_sync as cs +from pdd.commands.reconcile import reconcile + +REPO_ROOT = Path(__file__).resolve().parent.parent +STAMPER_PATH = REPO_ROOT / "scripts" / "stamp_fingerprints.py" + +_PDDRC = """version: "1.0" +contexts: + default: + paths: ["**"] + defaults: + generate_output_path: "pdd/" + test_output_path: "tests/" + example_output_path: "context/" + default_language: "python" +""" + + +# --- Fixture repo helpers ---------------------------------------------------- + + +def _make_repo(tmp_path: Path) -> Path: + (tmp_path / ".pddrc").write_text(_PDDRC, encoding="utf-8") + for sub in ("pdd/prompts", "context", "tests", ".pdd/meta"): + (tmp_path / sub).mkdir(parents=True, exist_ok=True) + return tmp_path + + +def _write_unit( # pylint: disable=too-many-arguments + root: Path, + basename: str, + *, + prompt: str = "describe the module\n", + code: str = "VALUE = 1\n", + example: str | None = None, + test: str | None = None, +) -> str: + """Write a flat unit's prompt/code (+optional example/test) into ``root``.""" + (root / "pdd" / "prompts" / f"{basename}_python.prompt").write_text( + prompt, encoding="utf-8" + ) + (root / "pdd" / f"{basename}.py").write_text(code, encoding="utf-8") + if example is not None: + (root / "context" / f"{basename}_example.py").write_text(example, encoding="utf-8") + if test is not None: + (root / "tests" / f"test_{basename}.py").write_text(test, encoding="utf-8") + return basename + + +def _classify_one(root: Path, basename: str) -> dict: + report = cs.build_report(consumer="test", root=root, modules=[basename]) + units = report["units"] + assert units, f"no unit classified for {basename}" + return units[0] + + +# --- Four statuses ----------------------------------------------------------- + + +def test_status_current(tmp_path): + """A baselined, unmodified unit is IN_SYNC / status current.""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha") + cs.stamp_units(cs.resolve_units(root), root) # baseline + verdict = _classify_one(root, "alpha") + assert verdict["classification"] == "IN_SYNC" + assert verdict["status"] == "current" + assert verdict["remediation"] == "" + + +def test_status_stamped_on_heal(tmp_path): + """Single-sided drift is stamped by --heal and becomes current.""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha", code="VALUE = 1\n") + cs.stamp_units(cs.resolve_units(root), root) + (root / "pdd" / "alpha.py").write_text("VALUE = 2 # hotfix\n", encoding="utf-8") + + drift = _classify_one(root, "alpha") + assert drift["classification"] == "CODE_CHANGED" + assert drift["status"] == "stale" + assert drift["remediation"] == "pdd update alpha" + + report = cs.build_report(consumer="test", root=root, modules=["alpha"], heal=True) + assert report["stamped"] == ["alpha"] + assert report["units"][0]["status"] == "stamped" + # Re-classify: now current. + assert _classify_one(root, "alpha")["classification"] == "IN_SYNC" + + +def test_status_conflict_not_stamped_without_accept(tmp_path): + """Prompt AND code both moved is CONFLICT; --heal must not stamp it.""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha", prompt="v0\n", code="VALUE = 1\n") + cs.stamp_units(cs.resolve_units(root), root) + (root / "pdd" / "prompts" / "alpha_python.prompt").write_text("v1\n", encoding="utf-8") + (root / "pdd" / "alpha.py").write_text("VALUE = 2\n", encoding="utf-8") + + verdict = _classify_one(root, "alpha") + assert verdict["classification"] == "CONFLICT" + assert verdict["status"] == "conflict" + assert "--accept-current" in verdict["remediation"] + + # --heal alone leaves a conflict untouched. + healed = cs.build_report(consumer="test", root=root, modules=["alpha"], heal=True) + assert not healed["stamped"] + assert _classify_one(root, "alpha")["classification"] == "CONFLICT" + + +def test_status_unbaselined_not_stamped_without_backfill(tmp_path): + """A unit with no fingerprint is UNBASELINED; --heal must not stamp it.""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha") # never baselined -> no meta + + verdict = _classify_one(root, "alpha") + assert verdict["classification"] == "UNBASELINED" + assert verdict["status"] == "unbaselined" + assert "--backfill" in verdict["remediation"] + + healed = cs.build_report(consumer="test", root=root, modules=["alpha"], heal=True) + assert not healed["stamped"] + assert _classify_one(root, "alpha")["classification"] == "UNBASELINED" + + +# --- Stamping scopes --------------------------------------------------------- + + +def test_accept_current_stamps_only_conflict(tmp_path): + """--accept-current stamps CONFLICT units and nothing else (no --heal).""" + root = _make_repo(tmp_path) + _write_unit(root, "conf", prompt="v0\n", code="C0\n") + _write_unit(root, "drift", code="D0\n") + cs.stamp_units(cs.resolve_units(root), root) + # conf: both sides move -> CONFLICT; drift: code only -> CODE_CHANGED + (root / "pdd" / "prompts" / "conf_python.prompt").write_text("v1\n", encoding="utf-8") + (root / "pdd" / "conf.py").write_text("C1\n", encoding="utf-8") + (root / "pdd" / "drift.py").write_text("D1\n", encoding="utf-8") + + report = cs.build_report(consumer="test", root=root, accept_current=True) + assert report["stamped"] == ["conf"] # drift NOT stamped (heal not set) + assert _classify_one(root, "drift")["classification"] == "CODE_CHANGED" + + +def test_backfill_stamps_only_unbaselined(tmp_path): + """--backfill stamps UNBASELINED units and nothing else (no --heal).""" + root = _make_repo(tmp_path) + _write_unit(root, "fresh") # unbaselined + _write_unit(root, "drift", code="D0\n") + # baseline only 'drift', then drift it + cs.stamp_units([cs.resolve_unit("drift", root)], root) + (root / "pdd" / "drift.py").write_text("D1\n", encoding="utf-8") + + report = cs.build_report(consumer="test", root=root, backfill=True) + assert report["stamped"] == ["fresh"] # drift NOT stamped + assert _classify_one(root, "fresh")["classification"] == "IN_SYNC" + assert _classify_one(root, "drift")["classification"] == "CODE_CHANGED" + + +# --- issue #884 verdict shape ------------------------------------------------ + + +def test_json_verdict_shape(tmp_path): + """Every verdict carries the #884 keys; report is JSON-serialisable.""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha") + cs.stamp_units(cs.resolve_units(root), root) + (root / "pdd" / "prompts" / "alpha_python.prompt").write_text("changed\n", encoding="utf-8") + + report = cs.build_report(consumer="test", root=root, modules=["alpha"]) + json.dumps(report) # must not raise + verdict = report["units"][0] + for key in ("status", "reasons", "affected_artifacts", "remediation", "classification"): + assert key in verdict + assert verdict["classification"] == "PROMPT_CHANGED" + assert verdict["affected_artifacts"] == ["prompt"] + assert isinstance(verdict["reasons"], list) and verdict["reasons"] + assert verdict["remediation"] == "pdd sync alpha" + + +# --- Idempotency ------------------------------------------------------------- + + +def test_second_stamp_run_is_noop(tmp_path): + """A repo-wide stamp writes changed units once; the second run writes nothing.""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha", code="A0\n") + _write_unit(root, "beta", code="B0\n") + cs.stamp_units(cs.resolve_units(root), root) # baseline both + (root / "pdd" / "alpha.py").write_text("A1\n", encoding="utf-8") + + first = cs.stamp_units(cs.resolve_units(root), root) + assert first == ["alpha"] + second = cs.stamp_units(cs.resolve_units(root), root) + assert not second # pdd#1932 DoD: second consecutive run is a no-op + + +def test_single_unit_touch(tmp_path): + """Stamping touches only the changed unit's fingerprint file.""" + root = _make_repo(tmp_path) + for name in ("alpha", "beta", "gamma"): + _write_unit(root, name, code=f"{name} = 0\n") + cs.stamp_units(cs.resolve_units(root), root) + + names = ("alpha", "beta", "gamma") + metas = {name: root / ".pdd" / "meta" / f"{name}_python.json" for name in names} + before = {name: path.read_bytes() for name, path in metas.items()} + (root / "pdd" / "beta.py").write_text("beta = 999\n", encoding="utf-8") + + written = cs.stamp_units(cs.resolve_units(root), root) + assert written == ["beta"] + assert metas["alpha"].read_bytes() == before["alpha"] # untouched + assert metas["gamma"].read_bytes() == before["gamma"] # untouched + assert metas["beta"].read_bytes() != before["beta"] # rewritten + + +# --- Resolution regressions (real repo) -------------------------------------- + + +@pytest.mark.parametrize( + "basename", ["commands/firecrawl", "core/remote_session", "remote_session"] +) +def test_resolution_regression_units_are_current(basename): + """The units #1954 mis-resolved now classify IN_SYNC on the committed tree. + + commands/firecrawl (underscore-basename resolved a stray flat test) and the + core/remote_session vs remote_session leaf collision were the two false + positives; correct resolution clears both. + """ + verdict = _classify_one(REPO_ROOT, basename) + assert verdict["classification"] == "IN_SYNC", verdict["reason"] + + +# --- Script <-> command parity ---------------------------------------------- + + +def _load_stamper(): + spec = importlib.util.spec_from_file_location("stamp_fingerprints", STAMPER_PATH) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def test_script_and_command_agree_on_clean_tree(): + """The CI stamper and `pdd reconcile --check` agree the committed tree is current.""" + assert cs.run_check(root=REPO_ROOT).ok is True + stamper = _load_stamper() + assert stamper.main(["--check"]) == 0 + + +# --- reconcile CLI surface --------------------------------------------------- + + +def test_cli_check_exit_codes(tmp_path, monkeypatch): + """`pdd reconcile --check` exits 0 when current, non-zero on drift (no writes).""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha", code="A0\n") + cs.stamp_units(cs.resolve_units(root), root) + monkeypatch.chdir(root) + runner = CliRunner() + + ok = runner.invoke(reconcile, ["--check"]) + assert ok.exit_code == 0, ok.output + assert "all fingerprints current" in ok.output + + (root / "pdd" / "alpha.py").write_text("A1\n", encoding="utf-8") + drifted = runner.invoke(reconcile, ["--check"]) + assert drifted.exit_code == 1, drifted.output + + +def test_cli_json_basename(tmp_path, monkeypatch): + """`pdd reconcile BASENAME --json` reports only that unit, with the #884 shape.""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha") + _write_unit(root, "beta") + cs.stamp_units(cs.resolve_units(root), root) + monkeypatch.chdir(root) + + result = CliRunner().invoke(reconcile, ["alpha", "--json"]) + assert result.exit_code == 0, result.output + payload = json.loads(result.output) + assert [u["basename"] for u in payload["units"]] == ["alpha"] + assert payload["units"][0]["status"] == "current" From 4d4c94a2d2cc506ea78cf6283b8088f33da752e6 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 15:54:19 -0700 Subject: [PATCH 27/30] Reconcile fingerprints after merging origin/main (deterministic restamp) Merged 25 upstream commits; main's code changes + new story_regression units restamped to the merged tree via scripts/stamp_fingerprints.py. Both gates green. Co-Authored-By: Claude Fable 5 --- .pdd/meta/auto_deps_main_python.json | 8 ++++---- .pdd/meta/checkup_prompt_main_python.json | 8 ++++---- .pdd/meta/cmd_test_main_python.json | 8 ++++---- .pdd/meta/commands_generate_python.json | 14 +++++++------- .pdd/meta/commands_maintenance_python.json | 8 ++++---- .pdd/meta/commands_misc_python.json | 8 ++++---- .pdd/meta/commands_story_python.json | 14 +++++++------- .pdd/meta/commands_templates_python.json | 8 ++++---- .pdd/meta/commands_utility_python.json | 8 ++++---- .pdd/meta/construct_paths_python.json | 8 ++++---- .pdd/meta/core_dump_python.json | 10 +++++----- .pdd/meta/core_errors_python.json | 10 +++++----- .pdd/meta/core_utils_python.json | 8 ++++---- .pdd/meta/coverage_contracts_python.json | 8 ++++---- .pdd/meta/detect_change_main_python.json | 8 ++++---- .pdd/meta/generate_output_paths_python.json | 8 ++++---- .pdd/meta/preprocess_main_python.json | 8 ++++---- .pdd/meta/split_main_python.json | 8 ++++---- .pdd/meta/story_coverage_python.json | 12 ++++++------ .pdd/meta/story_regression_gate_python.json | 14 +++++++------- .pdd/meta/story_regression_python.json | 18 +++++++++--------- .pdd/meta/sync_animation_python.json | 8 ++++---- .pdd/meta/sync_main_python.json | 8 ++++---- .pdd/meta/sync_orchestration_python.json | 8 ++++---- .pdd/meta/user_story_tests_python.json | 10 +++++----- 25 files changed, 119 insertions(+), 119 deletions(-) diff --git a/.pdd/meta/auto_deps_main_python.json b/.pdd/meta/auto_deps_main_python.json index 29b61d2259..a723e62d6e 100644 --- a/.pdd/meta/auto_deps_main_python.json +++ b/.pdd/meta/auto_deps_main_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.003360+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.252125+00:00", "command": "fix", - "prompt_hash": "811c79863b474bbbf78cd137e35aa2024e9a95b256752709328bbd5915a8637a", + "prompt_hash": "ca50e0c7d02d981a53548192ad3fc6b76bc25cee07b2e05d1d45090652d71f29", "code_hash": "b5df06f550c4dc0151af20f911eb19552d494cfb9853a7f35bd67c096a40581a", "example_hash": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "test_hash": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20", @@ -10,7 +10,7 @@ "test_auto_deps_main.py": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/insert_includes_example.py": "c304bf4656f75fa26192c92b3eb0422a903d8a1bc82dda3158dc9f184b337873", diff --git a/.pdd/meta/checkup_prompt_main_python.json b/.pdd/meta/checkup_prompt_main_python.json index aeca56ca12..bb91077d3b 100644 --- a/.pdd/meta/checkup_prompt_main_python.json +++ b/.pdd/meta/checkup_prompt_main_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.027976+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.280957+00:00", "command": "fix", - "prompt_hash": "a7e1a43ec7e38aecd73d9b4acaf142413c48d6df461d524c122f22bac10df8ef", + "prompt_hash": "e7423a67b6bfc98b14bd442622701daf3a9d875eafa9912a70d6b167fbf3f81a", "code_hash": "538367ba6b7fa74d9f86ba6d1235219598f7a124c58cf00ad0abf6cf027526dc", "example_hash": "04845b3c70203df3ce51d3c3a1aaac61bcb0089d2af3f7d92af73b7f923ab32c", "test_hash": "81f5c4befae10e8f4f1078f2e772db1646dd43c1bd24c541e8687a4659e760af", @@ -19,6 +19,6 @@ "pdd/gate_main.py": "8281d282d9ad62dc01c92c4f520ea0be70e5fba50281d18fd4111445ebfd613a", "pdd/prompt_lint.py": "df85f363082925c714e23be8d7b2e941d62a8542a3370a2581d16780cef1474e", "pdd/source_set_model.py": "72465c576d85e606d557e602ea78c8dc58646455a429a8dfa4e7b66da22210fa", - "pdd/user_story_tests.py": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc" + "pdd/user_story_tests.py": "48a1597e9b7cd409ab62e9ef6b005f5fdb29699207c24f640b149f7e79adf79b" } } \ No newline at end of file diff --git a/.pdd/meta/cmd_test_main_python.json b/.pdd/meta/cmd_test_main_python.json index f60879f84c..1f884b9e88 100644 --- a/.pdd/meta/cmd_test_main_python.json +++ b/.pdd/meta/cmd_test_main_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.048892+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.304021+00:00", "command": "fix", - "prompt_hash": "0c5ebbcaf3004ef236bf63fcc99a9694d0042648e179b922b8610734ad6046df", + "prompt_hash": "22b37ba5ebcdfafdc835a34e78de06bb9994da7996d2d4721886ddd1298c7d58", "code_hash": "cc809a1c54c8f4aa2ac4dd9e391d89df4b4e1be2dacc42f0a71306b4a666cf3d", "example_hash": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "test_hash": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643", @@ -10,7 +10,7 @@ "test_cmd_test_main.py": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/cloud_function_call.py": "62ac7724ce2e3eddbba2b743bd7aa5790dbed34eae01e77e0252c4cc6358c95e", diff --git a/.pdd/meta/commands_generate_python.json b/.pdd/meta/commands_generate_python.json index 20503921e2..3c0adaa206 100644 --- a/.pdd/meta/commands_generate_python.json +++ b/.pdd/meta/commands_generate_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.074689+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.334575+00:00", "command": "fix", - "prompt_hash": "8192f9b9659b22fbfab38d99fa9d7d7316b582c0a365e28405e0d09c5d2c872c", - "code_hash": "fc493964a405a7bc8444b131d27f98ca6af7cd08d569b99f09eb865a1eeae0b8", + "prompt_hash": "f538c52d5e7a071976cae837c14d570f8aeccf2ca9383c4fed48271dd21f3c4d", + "code_hash": "7751e368d656f940760d38cbe617011ae5f9dffcaed0ac3fd85ec1fd6b1567b5", "example_hash": "ecfaafca740d69b46d569368cb5a289410cf6fde5ef45c880bde396c797052c2", - "test_hash": "48a327fef36aee1f20360177bf65e862b57587d7977acc1d862352df8391eb97", + "test_hash": "f7603f270d2fbcd0a7623ddbd6bb63e1e3f33ae51868d163b9a3a5e3f58483a2", "test_files": { - "test_generate.py": "48a327fef36aee1f20360177bf65e862b57587d7977acc1d862352df8391eb97" + "test_generate.py": "f7603f270d2fbcd0a7623ddbd6bb63e1e3f33ae51868d163b9a3a5e3f58483a2" }, "include_deps": { "context/agentic_architecture_example.py": "f82ea3f16297c0cd0f7993549054bc9213953ebe03144aa5abc7bd74ba707e13", @@ -19,6 +19,6 @@ "context/operation_log_example.py": "2660def7012d9b79bad3db33cf399ac603cc1c35dff0b064cbdd2638a013de1d", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/track_cost_example.py": "bd60efaa7d6274b0e4d1743ac05785461af65ec785b254730288d08774f72ed6", - "pdd/user_story_tests.py": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc" + "pdd/user_story_tests.py": "48a1597e9b7cd409ab62e9ef6b005f5fdb29699207c24f640b149f7e79adf79b" } } \ No newline at end of file diff --git a/.pdd/meta/commands_maintenance_python.json b/.pdd/meta/commands_maintenance_python.json index 8641879fa3..5fc346d107 100644 --- a/.pdd/meta/commands_maintenance_python.json +++ b/.pdd/meta/commands_maintenance_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.078153+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.341602+00:00", "command": "fix", - "prompt_hash": "d14964561101841448e50fc0181f7cc11f5b4db633e85d0791badda3b05e5abb", + "prompt_hash": "368c6dcc28405c3d0462eb7c511ada142eaeef387e5a81083985847b4f89e63b", "code_hash": "4fa2499fe14940b0bd6858ca665870236c8be4342b7d44514d920381616b980a", "example_hash": "89252d2bb50c54846397d3ec319aae9ce69434d2af7a6d746dd7d85a317216e6", "test_hash": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a", @@ -10,7 +10,7 @@ "test_maintenance.py": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/commands_misc_python.json b/.pdd/meta/commands_misc_python.json index 2df1769273..a0be256011 100644 --- a/.pdd/meta/commands_misc_python.json +++ b/.pdd/meta/commands_misc_python.json @@ -1,14 +1,14 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.079806+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.344840+00:00", "command": "fix", - "prompt_hash": "b975c6437984acbd35a0e88ea1eb17ef2a2477c3b5a18d600c8c0800c93584f7", + "prompt_hash": "ab60c3d04716f93c78052e90fc834a8eb56e6d7651438560ae7ff8d16b07b7ae", "code_hash": "e49fff5cb806fc88e2ba5e54f445f2b2f855d6902946319c47a264ab6f13885c", "example_hash": "7d7985d21dd7b962257856cb92d13e26c016bc09ce14aaac4c68baaead97dc4b", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/preprocess_main_example.py": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/commands_story_python.json b/.pdd/meta/commands_story_python.json index c5a50a5d8d..9106266fab 100644 --- a/.pdd/meta/commands_story_python.json +++ b/.pdd/meta/commands_story_python.json @@ -1,16 +1,16 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.087441+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.355128+00:00", "command": "fix", - "prompt_hash": "8504142f3ab73f5beb85bc0f7bf5c5b92828bf54d1006e2c2cc6aa366a1cad7b", - "code_hash": "a72c43090f69470d83fa4ec5836cd1528c9f8c8d98f063468833afb61030e736", + "prompt_hash": "75668f6249cff70e5bb9d31517a60591a18264e5a347eaf938085f35a595e4f6", + "code_hash": "afd7ee5fde8aacd3691e321de48fa0d7dfb077413f7685393fa10adb5ad824fa", "example_hash": null, - "test_hash": "f727eec05860b2f06cab71af9b9b52f2e1a070b00e96840090b577e46f7e1779", + "test_hash": "71d27dbe130a088e83033618c5d1bfb98baf8d2841e20d55925e8b0390db548e", "test_files": { - "test_story.py": "f727eec05860b2f06cab71af9b9b52f2e1a070b00e96840090b577e46f7e1779" + "test_story.py": "71d27dbe130a088e83033618c5d1bfb98baf8d2841e20d55925e8b0390db548e" }, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", - "pdd/user_story_tests.py": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc" + "pdd/user_story_tests.py": "48a1597e9b7cd409ab62e9ef6b005f5fdb29699207c24f640b149f7e79adf79b" } } \ No newline at end of file diff --git a/.pdd/meta/commands_templates_python.json b/.pdd/meta/commands_templates_python.json index f26bb11368..61100f9ae5 100644 --- a/.pdd/meta/commands_templates_python.json +++ b/.pdd/meta/commands_templates_python.json @@ -1,14 +1,14 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.088838+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.357991+00:00", "command": "fix", - "prompt_hash": "2b47f34b85744c82929e50eab832849b11ef2edf73a5ba17e5dd6c6ef9d789d7", + "prompt_hash": "3e05ea9077de75e38af677efefb2078941dc56e9905d7fc51a2bb2ef0d4151ed", "code_hash": "6cb72959c02bcb9df6c2661ed339d61a782f4466980c0f899371af2113818dd0", "example_hash": "017d7a9cbdec60dd67cee662f3b21a68638137cd086fb335ef92889e1d91b09a", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/commands_utility_python.json b/.pdd/meta/commands_utility_python.json index 2689b5d77e..a065dd9c31 100644 --- a/.pdd/meta/commands_utility_python.json +++ b/.pdd/meta/commands_utility_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.091132+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.362001+00:00", "command": "fix", - "prompt_hash": "d4329af7e4dd671fae0033c60e9feb6ae0470cc12c320c5072b153a31eee39ba", + "prompt_hash": "dcc9cc2e0d8295bc6a5adef6b61a11d56c25b1937677142e10c6bc9206b0943b", "code_hash": "9d0f70da4a91baf636335b69168fff3806b48d8fa6bc6bf0ca8c910bf1f11559", "example_hash": "fb7389c0ec837b8b6ee481e2eda04800f565fe247643f5bb9922dd1dfdab984a", "test_hash": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31", @@ -10,7 +10,7 @@ "test_utility.py": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/fix_verification_main_example.py": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", "context/install_completion_example.py": "999be17c0ce476845d7048a1a909ad425e60c298dbc7c74f51b596ef134a8aec", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/construct_paths_python.json b/.pdd/meta/construct_paths_python.json index 84cc5cb5af..73a4062c6e 100644 --- a/.pdd/meta/construct_paths_python.json +++ b/.pdd/meta/construct_paths_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.101033+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.373924+00:00", "command": "fix", - "prompt_hash": "239d02a86a003a736e6f857c05fe5a62e92b26e9147769aa7388c3d244f3fa3b", + "prompt_hash": "4f7ff860528a08e7bedbad98863f84f19bba756f30d7fb55866d660f29efe90b", "code_hash": "7b42a002e4ecc27be4d517cbc07f1fc9425e795d4918714f382d2ed5ddd00eab", "example_hash": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "test_hash": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418", @@ -10,7 +10,7 @@ "test_construct_paths.py": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/generate_output_paths_example.py": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", diff --git a/.pdd/meta/core_dump_python.json b/.pdd/meta/core_dump_python.json index eb1f2973e3..c428385697 100644 --- a/.pdd/meta/core_dump_python.json +++ b/.pdd/meta/core_dump_python.json @@ -1,14 +1,14 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.119474+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.393510+00:00", "command": "fix", - "prompt_hash": "900d668f4ea02ae20cf5b3d9dbc3c34ff813ae02c7375cf705270f9c5360f33e", - "code_hash": "16e6786e459f4d82e38e909fa93ce5eef7b6b4284eef6dcaa3bab99f21406421", + "prompt_hash": "aa071d966753659fe81b9a9e58d3ef8a9af3db280f9fef820fc0ff40928e6108", + "code_hash": "658eb3a08930160339f1e5c73b9093b38ae4289191b4b63c7e92115b33728882", "example_hash": "0416a935ac490b958ceedfc6e68c7fbd7e383966374ba13ccf7ebfeaf8ad0803", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_errors_python.json b/.pdd/meta/core_errors_python.json index fb4ff61618..54fbb6ee2a 100644 --- a/.pdd/meta/core_errors_python.json +++ b/.pdd/meta/core_errors_python.json @@ -1,14 +1,14 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.122592+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.398454+00:00", "command": "fix", - "prompt_hash": "a4ed232076bf25996465aa91044edf73bde1a63d99fce6a4bf7c0dffb4fd3a39", - "code_hash": "fee544cef7641ad0b326790a4e90cc9d662a4bfcb01fac75aeb910ff85e56b84", + "prompt_hash": "635c378d63170d92b16ab16078f0bd5ad28d52d73c58ac3333087d2d688bd12a", + "code_hash": "8d6ab075c9667038bcd5c043ff888f3f531b179d6c1337fe806591a2ee4e708a", "example_hash": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_utils_python.json b/.pdd/meta/core_utils_python.json index 2fe9818dfd..157323ea8a 100644 --- a/.pdd/meta/core_utils_python.json +++ b/.pdd/meta/core_utils_python.json @@ -1,14 +1,14 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.124902+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.402265+00:00", "command": "fix", - "prompt_hash": "15b54fe34d3a28284b7a3c85a6afe06db0ba142849488d26bb7a29dafe06c498", + "prompt_hash": "5f1d5fa0ab7b1bd8256141b0ba0dfeb0ea9c57584b12f81dd38687afcfc3c277", "code_hash": "4386b3c9efd08ba0510aa80150b579f203fe9dbc32e047712599a34f55537191", "example_hash": "ecda9cd9c5910246e0f857eacacac6ec381eb531695e5a56670a9dd8c02c0ef1", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/coverage_contracts_python.json b/.pdd/meta/coverage_contracts_python.json index 1382161a47..fd2d993d15 100644 --- a/.pdd/meta/coverage_contracts_python.json +++ b/.pdd/meta/coverage_contracts_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.125958+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.404053+00:00", "command": "fix", "prompt_hash": "044980f2b8fe2bd1c0a3c294322b4e8767d9f12f8bb24410ba6e4ed818465dd8", "code_hash": "dc209452c683697866e133c5673a2caba1828c9e4836e012f277e0250a643c0c", "example_hash": null, - "test_hash": "ff6a64280a643dbfbec192aa22bbceb9ef6c9dacbec8ed73f58d1a666bcb9e93", + "test_hash": "b0229cfee890abcf8c9289183022c1e6409ed63df113dfebbaa1f0fffac161ac", "test_files": { - "test_coverage_contracts.py": "ff6a64280a643dbfbec192aa22bbceb9ef6c9dacbec8ed73f58d1a666bcb9e93" + "test_coverage_contracts.py": "b0229cfee890abcf8c9289183022c1e6409ed63df113dfebbaa1f0fffac161ac" }, "include_deps": {} } \ No newline at end of file diff --git a/.pdd/meta/detect_change_main_python.json b/.pdd/meta/detect_change_main_python.json index 1f8f2d60d7..4bb828a70a 100644 --- a/.pdd/meta/detect_change_main_python.json +++ b/.pdd/meta/detect_change_main_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.129579+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.410095+00:00", "command": "fix", - "prompt_hash": "4ce30e6306826a9e7e754287f8c7b5a3c78b18efa5a7e3035fbffe2ece13d63a", + "prompt_hash": "87fe6590da6720e1ac51eee021f2d2011561f76125088d85e5792537f41b9be3", "code_hash": "2ef7a1859b4195c37e441c7ec79c00cfdff81f68af80dc277a4ee88b586d923a", "example_hash": "ddc494709d127398004f53de58bede388692b2839a97b26668c55575369d9edd", "test_hash": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6", @@ -10,7 +10,7 @@ "test_detect_change_main.py": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", diff --git a/.pdd/meta/generate_output_paths_python.json b/.pdd/meta/generate_output_paths_python.json index e8bd2408db..e8f2a59c62 100644 --- a/.pdd/meta/generate_output_paths_python.json +++ b/.pdd/meta/generate_output_paths_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.166189+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.449349+00:00", "command": "fix", - "prompt_hash": "1e95a6b815495f5ffadd61e9bc5b36db6b47cb5d89f1c7a7b25ee89a7a13a751", + "prompt_hash": "97f15d5fd1d32cc1f484afa2bb32f3542e4b0aaa28ab523699d76097f884dd4b", "code_hash": "13890fe1983e3554b58f67404ce3848b3e9e329c03cf661446ad9ef62a71b43e", "example_hash": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "test_hash": "c0ed9c8db22f119f3849ee3e00d8bac35b8d67fc78dfcccc5d6fefc78d1f081a", @@ -11,7 +11,7 @@ "test_generate_output_paths_regression.py": "3763968e8dc0e661e6516520f9282776ae81f82d5207633926ccee6fd60d50ba" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74" } diff --git a/.pdd/meta/preprocess_main_python.json b/.pdd/meta/preprocess_main_python.json index 03fb395ec2..fdccb507fe 100644 --- a/.pdd/meta/preprocess_main_python.json +++ b/.pdd/meta/preprocess_main_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.216704+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.506852+00:00", "command": "fix", - "prompt_hash": "cecb0cae2711dd82a08c6b2041224c4e538e84e90b28f2e8035c877578ad69e6", + "prompt_hash": "c3e3aff39c454a856509ea4a232cae330f344974ffc161e521660950adb3a36b", "code_hash": "a069c3a73be88d3e3e93d40fd66e482c69bfb56ab627d862da31585612ac203b", "example_hash": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "test_hash": "0fa3887c7a4e2c3f051ce719117b8f07444da419b35363b9dff4a2b5ae0f17e9", @@ -11,7 +11,7 @@ "test_preprocess_main_pdd_tags.py": "abddfe41c460aa7dcd4186028134deb4eef0a85419a7f6f59869a274c25f7ee8" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/split_main_python.json b/.pdd/meta/split_main_python.json index a0b74a6f91..6c71ebbafe 100644 --- a/.pdd/meta/split_main_python.json +++ b/.pdd/meta/split_main_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.260795+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.558503+00:00", "command": "fix", - "prompt_hash": "54ac70b37397e1803b7d2bc051794c61e7601301d982c350157c5dbc21f42466", + "prompt_hash": "c86549e9227174ac9a5ec3d53fd04577a1bc8ddbfa29ef3c04d45640e8878b30", "code_hash": "381837b939069c6fef6c115caaefaa34c3103722de6ca95037ced13941edae75", "example_hash": "ced192fcbfbfda15b35bd2dad5bbf4b4888acb091084cf58326832d224a77661", "test_hash": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887", @@ -10,7 +10,7 @@ "test_split_main.py": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/story_coverage_python.json b/.pdd/meta/story_coverage_python.json index ebe1c108c2..de3d6aa2e6 100644 --- a/.pdd/meta/story_coverage_python.json +++ b/.pdd/meta/story_coverage_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.265081+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.565310+00:00", "command": "fix", - "prompt_hash": "372aa16676ec2f4f1e528dbb9c6335b24c4181c8b04123b064704f25cb9b479d", - "code_hash": "6d15872bac258806e49feda2cb37ff410d667930905eedec836192395cfd7f75", + "prompt_hash": "f87f5e1535e47a460b80bef1e5452899886ec2d6c4bdb1a153230e7bdc9d6a90", + "code_hash": "e7d0bd9054769ede102f721e343dc9da377961a228bd0dfbf92aaced93960a0b", "example_hash": "8dc2e6fea81ea2bab743ab5e22295e41eb277bc75cd553fb35278020dc4eef02", - "test_hash": "aec88c13736cd4b0dc40c841cfcd4299ce4f235294755f254d5ba0fe97ef934e", + "test_hash": "08c59062b5dcd4f23a08edceca64d5e9f3e87135298efda8be8fd4c3f61ae3ac", "test_files": { - "test_story_coverage.py": "aec88c13736cd4b0dc40c841cfcd4299ce4f235294755f254d5ba0fe97ef934e" + "test_story_coverage.py": "08c59062b5dcd4f23a08edceca64d5e9f3e87135298efda8be8fd4c3f61ae3ac" }, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" diff --git a/.pdd/meta/story_regression_gate_python.json b/.pdd/meta/story_regression_gate_python.json index ba5fa1ec17..25e51ab784 100644 --- a/.pdd/meta/story_regression_gate_python.json +++ b/.pdd/meta/story_regression_gate_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.265996+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.567924+00:00", "command": "fix", - "prompt_hash": "3c3381a2d75792bdc45e201fe44dc9a1b24cca4a1162c37b1415b043df9a52a9", - "code_hash": "51d3dc49dda8a594f71816a83143b1cc14b5c01ac917d17fd9505fc3da2ea06c", - "example_hash": null, - "test_hash": "95e60df5f061c90e881fc50d89870dd86cadf109627049a9dc729d4dab74e6f3", + "prompt_hash": "b7bda11ea95f0eeaf4d1f21f4d2eb3fa2c06fff9485dba4b4f4655c28b8df09c", + "code_hash": "bd4a4ff48aee34786e450ab17c113e74bb68c4f42221d9a17d6cfd5023ea82fc", + "example_hash": "b1afd246420e7fa92c0650c8739646b1a6d68a8cecb664881899a276774cf8c4", + "test_hash": "514ae8c1ebf5ccef73caa0aa521b49e2995e10c33ed3e6cc3723bea0576ce7e8", "test_files": { - "test_story_regression_gate.py": "95e60df5f061c90e881fc50d89870dd86cadf109627049a9dc729d4dab74e6f3" + "test_story_regression_gate.py": "514ae8c1ebf5ccef73caa0aa521b49e2995e10c33ed3e6cc3723bea0576ce7e8" }, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" diff --git a/.pdd/meta/story_regression_python.json b/.pdd/meta/story_regression_python.json index 5a25cf8ddc..9a3fcfec0b 100644 --- a/.pdd/meta/story_regression_python.json +++ b/.pdd/meta/story_regression_python.json @@ -1,17 +1,17 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.267424+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.570565+00:00", "command": "fix", - "prompt_hash": "689cbfe6e7648a9087f1f20aae4b80260ece0834c8b8673fdda254392d49bed1", - "code_hash": "7f3e89234750cf8483659ae2c409ee663d9b2b981b0689b9c9a69c6778a772d5", - "example_hash": null, - "test_hash": "919725a4142dd273cff39b3eba959ab50c18b4cde38139eb2559a1e191958bc9", + "prompt_hash": "8103e5b2755bf50a484a5f5cf420f2bb0e593c1f0d56d750573c99db81a85f77", + "code_hash": "1d921a6c4c8aefb97e4b5e5ce563c45273e14d8ca243ac147275d12d7b4aa94d", + "example_hash": "90aa347c0d78ae8e7e951cf390836da3778d7d9c70d7bd9407b7b1a1764c66f1", + "test_hash": "ea383b00fd2d08c7a0298f533d0d28b7d83bb1f0f5484da54c60514dcde8f045", "test_files": { - "test_story_regression.py": "919725a4142dd273cff39b3eba959ab50c18b4cde38139eb2559a1e191958bc9", - "test_story_regression_gate.py": "95e60df5f061c90e881fc50d89870dd86cadf109627049a9dc729d4dab74e6f3" + "test_story_regression.py": "ea383b00fd2d08c7a0298f533d0d28b7d83bb1f0f5484da54c60514dcde8f045", + "test_story_regression_gate.py": "514ae8c1ebf5ccef73caa0aa521b49e2995e10c33ed3e6cc3723bea0576ce7e8" }, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", - "context/user_story_tests_example.py": "ae08c16469db958715911eeedc5916eb68fc71c90b605c4b78f6e93096873c86" + "context/user_story_tests_example.py": "53214544b7af564ee41f178b9cbabc5162c9c6648638366f609a2ec5a46398d3" } } \ No newline at end of file diff --git a/.pdd/meta/sync_animation_python.json b/.pdd/meta/sync_animation_python.json index ce49b383a4..81619df2d8 100644 --- a/.pdd/meta/sync_animation_python.json +++ b/.pdd/meta/sync_animation_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.274297+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.577837+00:00", "command": "fix", - "prompt_hash": "e22434f9c40895e357448f09b4d0594214ce64040875bdbc8c02de0956e1433c", + "prompt_hash": "d7318954c8a7beb35236e3c501882a3d9d793258d5f46f48ba4b4dc2a0fab094", "code_hash": "b9261a68d14049db76c89179f98ee1c45a073cc9a656607d447612e23f68e285", "example_hash": "5b6a8af940fe44241889a279c1a8d3c978fe0c6ec3afc648510d8e33ffa7b18c", "test_hash": "f76041e4a4e313d3005d5961e76c3b08bfc26549e498d341cefe31560c328ebd", @@ -13,7 +13,7 @@ "test_sync_animation_phases.py": "fa098d0dc0e6bb3f1f45863c1d01cf1a798fdcbaa3a402025aa241a39faef76c" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/logo_animation_example.py": "f32a5cc330235c3b61fb16ac62d3ae7531c7c6dbc11af077fc79054736f0944d", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/sync_main_python.json b/.pdd/meta/sync_main_python.json index 978fe99f3f..6891292142 100644 --- a/.pdd/meta/sync_main_python.json +++ b/.pdd/meta/sync_main_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.283115+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.589611+00:00", "command": "fix", - "prompt_hash": "0d0a2ef9c0bddd8af0017bac0d520cb05905d63177f145b4a052ed1f7af4ac58", + "prompt_hash": "a5e0e301f67e24c03c0a425524f597cecf622a2269fe08b5e19c8067fd75185c", "code_hash": "cca0497f63c1f43f3e8c9359f6a6fa7d0e8b3e9a5082aa911294907b7515b602", "example_hash": "9a7961a4044a54c46ce6c43c8adbbb83da46f233d9c6a9eaa28302440c0052c0", "test_hash": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1", @@ -10,7 +10,7 @@ "test_sync_main.py": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1" }, "include_deps": { - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", diff --git a/.pdd/meta/sync_orchestration_python.json b/.pdd/meta/sync_orchestration_python.json index 13b96f1d95..1f4cd0b4d1 100644 --- a/.pdd/meta/sync_orchestration_python.json +++ b/.pdd/meta/sync_orchestration_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.288757+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.600950+00:00", "command": "fix", - "prompt_hash": "00792630056aed8504ee5bdd7cc76e266b905de39e1c8894fe046efb03fd2cf2", + "prompt_hash": "8ecc2fda31b554402d09634c23a256f0e86770b837a47818a6e72af0444795d5", "code_hash": "72a9e22929b3538e8c63915bf12568998d5ae1226d84b4518c6f4e460f06a2b6", "example_hash": "cc1313a948946026d418c85a07e5bf0eedeb5915c44d630440e489979755e1f7", "test_hash": "807987d709b08ea7064a727bfa536ffcd10441ec1742f4743e9a4c25b8f8a63f", @@ -11,7 +11,7 @@ }, "include_deps": { "docs/whitepaper.md": "3347db03fa35376024b59d8546efdf0858655746490561b88b710fa6b85017cc", - "README.md": "f7b48adad9a0c7d7e92f11cb206b7c41a149a4d8b563455373b09be05090f006", + "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", diff --git a/.pdd/meta/user_story_tests_python.json b/.pdd/meta/user_story_tests_python.json index c685115a9c..18436eb065 100644 --- a/.pdd/meta/user_story_tests_python.json +++ b/.pdd/meta/user_story_tests_python.json @@ -1,10 +1,10 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.308155+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-09T22:54:16.624434+00:00", "command": "fix", - "prompt_hash": "18dd7b5a64063a5a942be847810537e6a22b436046bb698f1e891e3ebc2d5463", - "code_hash": "2acfe057044707b6f7ea547eb6009bf1a5c498fa66209f999c1030a0aeaea7bc", - "example_hash": "ae08c16469db958715911eeedc5916eb68fc71c90b605c4b78f6e93096873c86", + "prompt_hash": "9c69ba13bbca4e3b342eff0d14380e7e9a1bd5ff95fee922f4677fdad0d85bac", + "code_hash": "48a1597e9b7cd409ab62e9ef6b005f5fdb29699207c24f640b149f7e79adf79b", + "example_hash": "53214544b7af564ee41f178b9cbabc5162c9c6648638366f609a2ec5a46398d3", "test_hash": "8f9e336d3366396f4b8ff783eabf3c49df24a173c11a70972a5e13bc9ed43259", "test_files": { "test_user_story_tests.py": "8f9e336d3366396f4b8ff783eabf3c49df24a173c11a70972a5e13bc9ed43259" From dc90ff80b1caaa8602b35a9473a3cf0814d04ef3 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 19:23:14 -0700 Subject: [PATCH 28/30] Fix gate blindness on leaf-twin path-qualified units (#1969 review finding 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commands/checkup_simplify and core/remote_session resolved to their same-named LEAF files (pdd/checkup_simplify.py, pdd/remote_session.py) because architecture.json had no path-qualified entry, so the resolver fell back to the leaf — the fingerprint tracked the wrong file and edits to the real command/core file were invisible to the gate. Add the 2 missing architecture.json entries + restamp; edits now flag. Co-Authored-By: Claude Fable 5 --- .pdd/meta/checkup_simplify_python.json | 8 ++-- .../commands_checkup_simplify_python.json | 12 +++--- .pdd/meta/core_remote_session_python.json | 12 +++--- .pdd/meta/remote_session_python.json | 12 +++--- architecture.json | 43 +++++++++++++++++++ 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/.pdd/meta/checkup_simplify_python.json b/.pdd/meta/checkup_simplify_python.json index 5458c0b855..92c48b51fe 100644 --- a/.pdd/meta/checkup_simplify_python.json +++ b/.pdd/meta/checkup_simplify_python.json @@ -1,14 +1,12 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.035461+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-10T02:22:51.413274+00:00", "command": "fix", "prompt_hash": "3a0b375fbd9294ef119fed542d772ad16485ab579fe15fd55619e363d08e10a2", "code_hash": "6ec8b1694b0ec8c9955261fff159b1a86397d54f24a0f95ea5243ac9cbd6df7f", "example_hash": null, "test_hash": null, - "test_files": { - "test_checkup_simplify_engines.py": "e1ae900756abdba9805b2e50002811d22e48afb3ebe3fea3b60b7cd003487984" - }, + "test_files": {}, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/commands_checkup_simplify_python.json b/.pdd/meta/commands_checkup_simplify_python.json index 4e04cff2fb..06a50f4e4b 100644 --- a/.pdd/meta/commands_checkup_simplify_python.json +++ b/.pdd/meta/commands_checkup_simplify_python.json @@ -1,14 +1,12 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.065032+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-10T02:22:51.446610+00:00", "command": "fix", "prompt_hash": "879ba667d716fcf666ee1df507348749953d0dfba4e099fa0a9bac016945e101", - "code_hash": "6ec8b1694b0ec8c9955261fff159b1a86397d54f24a0f95ea5243ac9cbd6df7f", + "code_hash": "8f469665e09459f6405617c84214475a15f6b2353842f9b477c2089b437bf0a0", "example_hash": null, - "test_hash": "2a80956f21f2873e3eb48a113c6f756019db9e9b74b8a5e91e9052648caf8707", - "test_files": { - "test_checkup_simplify.py": "2a80956f21f2873e3eb48a113c6f756019db9e9b74b8a5e91e9052648caf8707" - }, + "test_hash": null, + "test_files": {}, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/core_remote_session_python.json b/.pdd/meta/core_remote_session_python.json index 8637a9671d..4c8d6b3d7d 100644 --- a/.pdd/meta/core_remote_session_python.json +++ b/.pdd/meta/core_remote_session_python.json @@ -1,14 +1,12 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.123671+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-10T02:22:51.513760+00:00", "command": "fix", "prompt_hash": "cbfe9e8449a09296501889ea92a9a2cae7b5743592ad2632b139e5423c1bab77", - "code_hash": "163292e0200246767f685e9478c8ab4531c06ba471be4ceb9a6ee8065b1cfc12", + "code_hash": "578e98f63ccacd49af41b7d17a31460a2eedffd8648e9fcaefc54fc17d0d3ffb", "example_hash": null, - "test_hash": "1705a65e3662a75acce9df73888da9de0e1cf3a4e6f2fa72db343dcd959ebbc3", - "test_files": { - "test_remote_session.py": "1705a65e3662a75acce9df73888da9de0e1cf3a4e6f2fa72db343dcd959ebbc3" - }, + "test_hash": null, + "test_files": {}, "include_deps": { "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/remote_session_python.json b/.pdd/meta/remote_session_python.json index e135d97822..35f4681a3b 100644 --- a/.pdd/meta/remote_session_python.json +++ b/.pdd/meta/remote_session_python.json @@ -1,14 +1,12 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.229340+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-10T02:22:51.624312+00:00", "command": "fix", "prompt_hash": "9a49cada503bed5d892ea7b68570c6357b6ee220a2f5a41ba1e37204f61e6760", "code_hash": "163292e0200246767f685e9478c8ab4531c06ba471be4ceb9a6ee8065b1cfc12", - "example_hash": "ebcf3626cc73386164ac48e804e2e7973cb9783892ac88cda49779cf158389c5", - "test_hash": "3beca26794e2f665a1052ba5dfa8a54bd90c4587c02c9c2fa03c7b85d1725e39", - "test_files": { - "test_remote_session.py": "3beca26794e2f665a1052ba5dfa8a54bd90c4587c02c9c2fa03c7b85d1725e39" - }, + "example_hash": null, + "test_hash": null, + "test_files": {}, "include_deps": { "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", "context/cloud_example.py": "92418beb7a1e7f25682bf2abce5b19013b95e7eed95256c930b83c1dd6dbfb0a", diff --git a/architecture.json b/architecture.json index 3f7c46d34e..267590ae21 100644 --- a/architecture.json +++ b/architecture.json @@ -12720,5 +12720,48 @@ ] } } + }, + { + "reason": "Registers the `pdd checkup simplify` CLI command (multi-provider simplify integration).", + "description": "Defines the `simplify` Click command that dispatches to run_checkup_simplify across engines (claude/codex/gemini/opencode/auto), with --apply/--engine/--path options; a thin command wrapper over pdd/checkup_simplify.py.", + "dependencies": [], + "priority": 278, + "filename": "commands/checkup_simplify_python.prompt", + "filepath": "pdd/commands/checkup_simplify.py", + "tags": [], + "interface": { + "type": "module", + "functions": [ + { + "name": "checkup_simplify", + "signature": "(ctx: click.Context)", + "returns": "Optional[Tuple[str, float, str]]" + } + ] + } + }, + { + "reason": "Detects whether pdd runs in a remote/SSH or headless session (for interactive-flow decisions).", + "description": "is_remote_session() inspects SSH_* env vars, DISPLAY, and WSL/WSLg to return (is_remote, reason); used to gate interactive prompts and browser flows.", + "dependencies": [], + "priority": 279, + "filename": "core/remote_session_python.prompt", + "filepath": "pdd/core/remote_session.py", + "tags": [], + "interface": { + "type": "module", + "functions": [ + { + "name": "is_remote_session", + "signature": "()", + "returns": "Tuple[bool, str]" + }, + { + "name": "should_skip_browser", + "signature": "(explicit_flag: Optional[bool])", + "returns": "Tuple[bool, str]" + } + ] + } } ] From 496b55e604bf553553090e740f37ca56cc152d97 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 19:30:14 -0700 Subject: [PATCH 29/30] Address #1969 review: resolve CONFLICT-guard, honest conflict message, docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finding 2: 'pdd resolve --accept-current' now REQUIRES a CONFLICT — single-sided (code-only/prompt-only) drift is refused with a redirect to pdd update/pdd sync/ pdd reconcile --heal, so it can't silently baseline real drift. Added --force escape hatch + IN_SYNC no-op. New tests cover refuse/force/no-op. Finding 3: the CONFLICT message no longer advertises the --prompt-wins/--code-wins preview stubs as resolutions; it points at the real runnable commands (pdd update / pdd sync) plus pdd resolve --accept-current. Updated the prompt spec + tests. Docs: README no longer tells users to delete .pdd/meta/*.json (contradicted the never-hand-edit policy) — points to pdd reconcile --heal. Documented the 6 prompt-less pdd/commands wrappers (incl. resolve/reconcile) in architecture_waivers. Restamped affected fingerprints. Gates + resolver/resolve/sync/orchestration tests green. Co-Authored-By: Claude Fable 5 --- .pdd/meta/auto_deps_main_python.json | 6 +- .pdd/meta/cmd_test_main_python.json | 6 +- .pdd/meta/commands_maintenance_python.json | 6 +- .pdd/meta/commands_misc_python.json | 6 +- .pdd/meta/commands_templates_python.json | 6 +- .pdd/meta/commands_utility_python.json | 6 +- .pdd/meta/construct_paths_python.json | 6 +- .pdd/meta/core_dump_python.json | 6 +- .pdd/meta/core_errors_python.json | 6 +- .pdd/meta/core_utils_python.json | 6 +- .pdd/meta/detect_change_main_python.json | 6 +- .pdd/meta/generate_output_paths_python.json | 6 +- .pdd/meta/metadata_sync_python.json | 8 +-- .pdd/meta/pre_checkup_gate_python.json | 8 +-- .pdd/meta/preprocess_main_python.json | 6 +- .pdd/meta/split_main_python.json | 6 +- .pdd/meta/sync_animation_python.json | 6 +- .../meta/sync_determine_operation_python.json | 12 ++-- .pdd/meta/sync_main_python.json | 6 +- .pdd/meta/sync_orchestration_python.json | 6 +- README.md | 2 +- architecture_waivers.json | 9 +++ pdd/commands/resolve.py | 62 ++++++++++++++++++- .../sync_determine_operation_python.prompt | 2 +- pdd/sync_determine_operation.py | 24 ++++--- tests/test_resolve_command.py | 59 ++++++++++++++++++ tests/test_sync_determine_operation.py | 14 +++-- 27 files changed, 221 insertions(+), 81 deletions(-) diff --git a/.pdd/meta/auto_deps_main_python.json b/.pdd/meta/auto_deps_main_python.json index a723e62d6e..5d126ea744 100644 --- a/.pdd/meta/auto_deps_main_python.json +++ b/.pdd/meta/auto_deps_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.252125+00:00", + "timestamp": "2026-07-10T02:29:20.596677+00:00", "command": "fix", - "prompt_hash": "ca50e0c7d02d981a53548192ad3fc6b76bc25cee07b2e05d1d45090652d71f29", + "prompt_hash": "aa9941eb508dcdabb3055f678512805b3c3d15d9f593da5b974ad55d49cd53e1", "code_hash": "b5df06f550c4dc0151af20f911eb19552d494cfb9853a7f35bd67c096a40581a", "example_hash": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "test_hash": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20", @@ -10,7 +10,7 @@ "test_auto_deps_main.py": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/insert_includes_example.py": "c304bf4656f75fa26192c92b3eb0422a903d8a1bc82dda3158dc9f184b337873", diff --git a/.pdd/meta/cmd_test_main_python.json b/.pdd/meta/cmd_test_main_python.json index 1f884b9e88..43329d1bd5 100644 --- a/.pdd/meta/cmd_test_main_python.json +++ b/.pdd/meta/cmd_test_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.304021+00:00", + "timestamp": "2026-07-10T02:29:20.647286+00:00", "command": "fix", - "prompt_hash": "22b37ba5ebcdfafdc835a34e78de06bb9994da7996d2d4721886ddd1298c7d58", + "prompt_hash": "aa1735966c2d592d9c58a2b848d99dd640cf6fc91cbb9123c67705e017e9cd7a", "code_hash": "cc809a1c54c8f4aa2ac4dd9e391d89df4b4e1be2dacc42f0a71306b4a666cf3d", "example_hash": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "test_hash": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643", @@ -10,7 +10,7 @@ "test_cmd_test_main.py": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/cloud_function_call.py": "62ac7724ce2e3eddbba2b743bd7aa5790dbed34eae01e77e0252c4cc6358c95e", diff --git a/.pdd/meta/commands_maintenance_python.json b/.pdd/meta/commands_maintenance_python.json index 5fc346d107..e65035f999 100644 --- a/.pdd/meta/commands_maintenance_python.json +++ b/.pdd/meta/commands_maintenance_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.341602+00:00", + "timestamp": "2026-07-10T02:29:20.683001+00:00", "command": "fix", - "prompt_hash": "368c6dcc28405c3d0462eb7c511ada142eaeef387e5a81083985847b4f89e63b", + "prompt_hash": "0b65467c46b879918e96569280f2ea87954e0e5296c1f21bee94e45c0678007d", "code_hash": "4fa2499fe14940b0bd6858ca665870236c8be4342b7d44514d920381616b980a", "example_hash": "89252d2bb50c54846397d3ec319aae9ce69434d2af7a6d746dd7d85a317216e6", "test_hash": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a", @@ -10,7 +10,7 @@ "test_maintenance.py": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/commands_misc_python.json b/.pdd/meta/commands_misc_python.json index a0be256011..35cf4c1e19 100644 --- a/.pdd/meta/commands_misc_python.json +++ b/.pdd/meta/commands_misc_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.344840+00:00", + "timestamp": "2026-07-10T02:29:20.686448+00:00", "command": "fix", - "prompt_hash": "ab60c3d04716f93c78052e90fc834a8eb56e6d7651438560ae7ff8d16b07b7ae", + "prompt_hash": "c5d8227f587562836a2ccbced292c1c5db67522c39afbc00d086addbe4b9261f", "code_hash": "e49fff5cb806fc88e2ba5e54f445f2b2f855d6902946319c47a264ab6f13885c", "example_hash": "7d7985d21dd7b962257856cb92d13e26c016bc09ce14aaac4c68baaead97dc4b", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/preprocess_main_example.py": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/commands_templates_python.json b/.pdd/meta/commands_templates_python.json index 61100f9ae5..a8ef18e697 100644 --- a/.pdd/meta/commands_templates_python.json +++ b/.pdd/meta/commands_templates_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.357991+00:00", + "timestamp": "2026-07-10T02:29:20.698902+00:00", "command": "fix", - "prompt_hash": "3e05ea9077de75e38af677efefb2078941dc56e9905d7fc51a2bb2ef0d4151ed", + "prompt_hash": "f1d5e36e3523c9524c2286efee6736f0c823f6b8a8cb99a993d305e63b823c69", "code_hash": "6cb72959c02bcb9df6c2661ed339d61a782f4466980c0f899371af2113818dd0", "example_hash": "017d7a9cbdec60dd67cee662f3b21a68638137cd086fb335ef92889e1d91b09a", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/commands_utility_python.json b/.pdd/meta/commands_utility_python.json index a065dd9c31..a56fad8713 100644 --- a/.pdd/meta/commands_utility_python.json +++ b/.pdd/meta/commands_utility_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.362001+00:00", + "timestamp": "2026-07-10T02:29:20.703842+00:00", "command": "fix", - "prompt_hash": "dcc9cc2e0d8295bc6a5adef6b61a11d56c25b1937677142e10c6bc9206b0943b", + "prompt_hash": "425ea87acc63af610131c19858b2f58ce8a6348cdeeb063ed36c47ce14b4380e", "code_hash": "9d0f70da4a91baf636335b69168fff3806b48d8fa6bc6bf0ca8c910bf1f11559", "example_hash": "fb7389c0ec837b8b6ee481e2eda04800f565fe247643f5bb9922dd1dfdab984a", "test_hash": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31", @@ -10,7 +10,7 @@ "test_utility.py": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/fix_verification_main_example.py": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", "context/install_completion_example.py": "999be17c0ce476845d7048a1a909ad425e60c298dbc7c74f51b596ef134a8aec", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/construct_paths_python.json b/.pdd/meta/construct_paths_python.json index 73a4062c6e..ac0f87be1e 100644 --- a/.pdd/meta/construct_paths_python.json +++ b/.pdd/meta/construct_paths_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.373924+00:00", + "timestamp": "2026-07-10T02:29:20.717094+00:00", "command": "fix", - "prompt_hash": "4f7ff860528a08e7bedbad98863f84f19bba756f30d7fb55866d660f29efe90b", + "prompt_hash": "474048402f0cc4beca9563ddedf25a08ab6e2d7b1027e4fe0f2c6f91d47eb9f1", "code_hash": "7b42a002e4ecc27be4d517cbc07f1fc9425e795d4918714f382d2ed5ddd00eab", "example_hash": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "test_hash": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418", @@ -10,7 +10,7 @@ "test_construct_paths.py": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/generate_output_paths_example.py": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", diff --git a/.pdd/meta/core_dump_python.json b/.pdd/meta/core_dump_python.json index c428385697..f8a8e6f222 100644 --- a/.pdd/meta/core_dump_python.json +++ b/.pdd/meta/core_dump_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.393510+00:00", + "timestamp": "2026-07-10T02:29:20.737243+00:00", "command": "fix", - "prompt_hash": "aa071d966753659fe81b9a9e58d3ef8a9af3db280f9fef820fc0ff40928e6108", + "prompt_hash": "7742acf1b2b29d5a1ba372549023c3cb16c02c3969ce606cdb91e73ef9078f8b", "code_hash": "658eb3a08930160339f1e5c73b9093b38ae4289191b4b63c7e92115b33728882", "example_hash": "0416a935ac490b958ceedfc6e68c7fbd7e383966374ba13ccf7ebfeaf8ad0803", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_errors_python.json b/.pdd/meta/core_errors_python.json index 54fbb6ee2a..dabb0f06ac 100644 --- a/.pdd/meta/core_errors_python.json +++ b/.pdd/meta/core_errors_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.398454+00:00", + "timestamp": "2026-07-10T02:29:20.741931+00:00", "command": "fix", - "prompt_hash": "635c378d63170d92b16ab16078f0bd5ad28d52d73c58ac3333087d2d688bd12a", + "prompt_hash": "6a7cc275f7672dc33af6101f135e93620e171e9057f645be2858906044ff3316", "code_hash": "8d6ab075c9667038bcd5c043ff888f3f531b179d6c1337fe806591a2ee4e708a", "example_hash": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_utils_python.json b/.pdd/meta/core_utils_python.json index 157323ea8a..86c50c9555 100644 --- a/.pdd/meta/core_utils_python.json +++ b/.pdd/meta/core_utils_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.402265+00:00", + "timestamp": "2026-07-10T02:29:20.745383+00:00", "command": "fix", - "prompt_hash": "5f1d5fa0ab7b1bd8256141b0ba0dfeb0ea9c57584b12f81dd38687afcfc3c277", + "prompt_hash": "cec19b8cdec7c25647fa3516a0bcab52d7cdbfdba2c2765dc1e21c8a4389c5a4", "code_hash": "4386b3c9efd08ba0510aa80150b579f203fe9dbc32e047712599a34f55537191", "example_hash": "ecda9cd9c5910246e0f857eacacac6ec381eb531695e5a56670a9dd8c02c0ef1", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/detect_change_main_python.json b/.pdd/meta/detect_change_main_python.json index 4bb828a70a..22bb9ab422 100644 --- a/.pdd/meta/detect_change_main_python.json +++ b/.pdd/meta/detect_change_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.410095+00:00", + "timestamp": "2026-07-10T02:29:20.752601+00:00", "command": "fix", - "prompt_hash": "87fe6590da6720e1ac51eee021f2d2011561f76125088d85e5792537f41b9be3", + "prompt_hash": "2c51643743f8c06f81886d0df773e20ae8ef96f817cf29edb7ca8f4a08aad31b", "code_hash": "2ef7a1859b4195c37e441c7ec79c00cfdff81f68af80dc277a4ee88b586d923a", "example_hash": "ddc494709d127398004f53de58bede388692b2839a97b26668c55575369d9edd", "test_hash": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6", @@ -10,7 +10,7 @@ "test_detect_change_main.py": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", diff --git a/.pdd/meta/generate_output_paths_python.json b/.pdd/meta/generate_output_paths_python.json index e8f2a59c62..64aee8c8d2 100644 --- a/.pdd/meta/generate_output_paths_python.json +++ b/.pdd/meta/generate_output_paths_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.449349+00:00", + "timestamp": "2026-07-10T02:29:20.791670+00:00", "command": "fix", - "prompt_hash": "97f15d5fd1d32cc1f484afa2bb32f3542e4b0aaa28ab523699d76097f884dd4b", + "prompt_hash": "c99f2d991b831b176ec29b5d466bf1699ca8668d684c0373e802f5880a7a04bb", "code_hash": "13890fe1983e3554b58f67404ce3848b3e9e329c03cf661446ad9ef62a71b43e", "example_hash": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "test_hash": "c0ed9c8db22f119f3849ee3e00d8bac35b8d67fc78dfcccc5d6fefc78d1f081a", @@ -11,7 +11,7 @@ "test_generate_output_paths_regression.py": "3763968e8dc0e661e6516520f9282776ae81f82d5207633926ccee6fd60d50ba" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74" } diff --git a/.pdd/meta/metadata_sync_python.json b/.pdd/meta/metadata_sync_python.json index d446ac6fbf..4c9684c241 100644 --- a/.pdd/meta/metadata_sync_python.json +++ b/.pdd/meta/metadata_sync_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.200247+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-10T02:29:20.829381+00:00", "command": "fix", - "prompt_hash": "ec39af8e67928925ff79e523ad4abb47bff291fe7996b13f23b91bf7a6aa879a", + "prompt_hash": "0ccbe8cdb8576ac8a3cea4df0d381d33e8ceb79ae9f113ec0596fb517c0b1192", "code_hash": "3afaa5a409e500b3f91aab33dacee33fae47447fba80a1702d65a33761261782", "example_hash": "704453b3386724eef225b61c48f2fe922e1a973ac211c494e1d955dd44bcca11", "test_hash": "82af9e0bff7550d1f9bf46f4c6e7f4792143565e4e228d1507976f6b9fbac5f6", @@ -14,6 +14,6 @@ "pdd/architecture_registry.py": "5722225846b9cc8189b410a78e5714b4f2916d5748271d27f6f738692429c309", "pdd/architecture_sync.py": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", - "pdd/sync_determine_operation.py": "764fc1f22c682fd6bb146731060a20f33a2c1caf921079abcda385a7be443a81" + "pdd/sync_determine_operation.py": "c3020b343e614a5c2532aa80b07d43d1c3f1ccc4d9ed33fdce6ade4258084b15" } } \ No newline at end of file diff --git a/.pdd/meta/pre_checkup_gate_python.json b/.pdd/meta/pre_checkup_gate_python.json index 59fd11c902..2998963c98 100644 --- a/.pdd/meta/pre_checkup_gate_python.json +++ b/.pdd/meta/pre_checkup_gate_python.json @@ -1,8 +1,8 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.214341+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-10T02:29:20.846988+00:00", "command": "fix", - "prompt_hash": "c3b8587745897302c814327cecd1f09db60d92dee4b3506a42a6d42b93f95308", + "prompt_hash": "214ed43f7a8606403192cb8f85fe1a3a724da727ae925b9a7bb5823c1da01dd3", "code_hash": "9ff0bbaa18c82cf4da836126861c40936a4555b8ff972f4bceee370492f37ace", "example_hash": "82585fac9350c3436528870c0b1d7e64228e6903cc4b5d0a62a35edecb266906", "test_hash": "d22520612cce8bf31712ff999b5f5f45153ddcd63a4044eb82c220d4a8021f62", @@ -16,6 +16,6 @@ "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "pdd/checkup_gates.py": "b6086954a93e0495661e6ca39d96b3079b928d13308bf0fcd6a16b1e0b5f511c", "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", - "pdd/sync_determine_operation.py": "764fc1f22c682fd6bb146731060a20f33a2c1caf921079abcda385a7be443a81" + "pdd/sync_determine_operation.py": "c3020b343e614a5c2532aa80b07d43d1c3f1ccc4d9ed33fdce6ade4258084b15" } } \ No newline at end of file diff --git a/.pdd/meta/preprocess_main_python.json b/.pdd/meta/preprocess_main_python.json index fdccb507fe..94b91bb34c 100644 --- a/.pdd/meta/preprocess_main_python.json +++ b/.pdd/meta/preprocess_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.506852+00:00", + "timestamp": "2026-07-10T02:29:20.851870+00:00", "command": "fix", - "prompt_hash": "c3e3aff39c454a856509ea4a232cae330f344974ffc161e521660950adb3a36b", + "prompt_hash": "0f7acb8c766d59a20a9ef3e0c74e70675bff4d92be019f62069081383778425b", "code_hash": "a069c3a73be88d3e3e93d40fd66e482c69bfb56ab627d862da31585612ac203b", "example_hash": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "test_hash": "0fa3887c7a4e2c3f051ce719117b8f07444da419b35363b9dff4a2b5ae0f17e9", @@ -11,7 +11,7 @@ "test_preprocess_main_pdd_tags.py": "abddfe41c460aa7dcd4186028134deb4eef0a85419a7f6f59869a274c25f7ee8" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/split_main_python.json b/.pdd/meta/split_main_python.json index 6c71ebbafe..514999afc6 100644 --- a/.pdd/meta/split_main_python.json +++ b/.pdd/meta/split_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.558503+00:00", + "timestamp": "2026-07-10T02:29:20.902273+00:00", "command": "fix", - "prompt_hash": "c86549e9227174ac9a5ec3d53fd04577a1bc8ddbfa29ef3c04d45640e8878b30", + "prompt_hash": "b81b93b2a60f31599407949c1b17d496c725d38f76843b32d5040b32708a61ce", "code_hash": "381837b939069c6fef6c115caaefaa34c3103722de6ca95037ced13941edae75", "example_hash": "ced192fcbfbfda15b35bd2dad5bbf4b4888acb091084cf58326832d224a77661", "test_hash": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887", @@ -10,7 +10,7 @@ "test_split_main.py": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/sync_animation_python.json b/.pdd/meta/sync_animation_python.json index 81619df2d8..d30e1d79b3 100644 --- a/.pdd/meta/sync_animation_python.json +++ b/.pdd/meta/sync_animation_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.577837+00:00", + "timestamp": "2026-07-10T02:29:20.916920+00:00", "command": "fix", - "prompt_hash": "d7318954c8a7beb35236e3c501882a3d9d793258d5f46f48ba4b4dc2a0fab094", + "prompt_hash": "d49c350fbcaf20a01486aeb160b769f75aeef1af2a79616c2cd51f453e6a0c12", "code_hash": "b9261a68d14049db76c89179f98ee1c45a073cc9a656607d447612e23f68e285", "example_hash": "5b6a8af940fe44241889a279c1a8d3c978fe0c6ec3afc648510d8e33ffa7b18c", "test_hash": "f76041e4a4e313d3005d5961e76c3b08bfc26549e498d341cefe31560c328ebd", @@ -13,7 +13,7 @@ "test_sync_animation_phases.py": "fa098d0dc0e6bb3f1f45863c1d01cf1a798fdcbaa3a402025aa241a39faef76c" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/logo_animation_example.py": "f32a5cc330235c3b61fb16ac62d3ae7531c7c6dbc11af077fc79054736f0944d", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/sync_determine_operation_python.json b/.pdd/meta/sync_determine_operation_python.json index f8805e53ca..a10126d713 100644 --- a/.pdd/meta/sync_determine_operation_python.json +++ b/.pdd/meta/sync_determine_operation_python.json @@ -1,13 +1,13 @@ { - "pdd_version": "0.0.299", - "timestamp": "2026-07-09T20:41:18.278998+00:00", + "pdd_version": "0.0.300.dev0", + "timestamp": "2026-07-10T02:29:20.923759+00:00", "command": "fix", - "prompt_hash": "d09025959647edcc9076cb860723b3c563ab08415a021656dc2274421c576759", - "code_hash": "764fc1f22c682fd6bb146731060a20f33a2c1caf921079abcda385a7be443a81", + "prompt_hash": "8800e2a4bdc8a41cc66b6c1300d7d3907cd738766ff20311ea8d6f239aeecbcc", + "code_hash": "c3020b343e614a5c2532aa80b07d43d1c3f1ccc4d9ed33fdce6ade4258084b15", "example_hash": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5", - "test_hash": "214be5ec2ee7563ce922ba7a3a9a860ee5b4a24c1c98cca946ce7664fa24343d", + "test_hash": "f6b580299672d687f1e45abae8be179c55f4a584bec57589de3ed7d13665e5c1", "test_files": { - "test_sync_determine_operation.py": "214be5ec2ee7563ce922ba7a3a9a860ee5b4a24c1c98cca946ce7664fa24343d" + "test_sync_determine_operation.py": "f6b580299672d687f1e45abae8be179c55f4a584bec57589de3ed7d13665e5c1" }, "include_deps": { "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", diff --git a/.pdd/meta/sync_main_python.json b/.pdd/meta/sync_main_python.json index 6891292142..92872f1c0e 100644 --- a/.pdd/meta/sync_main_python.json +++ b/.pdd/meta/sync_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.589611+00:00", + "timestamp": "2026-07-10T02:29:20.931566+00:00", "command": "fix", - "prompt_hash": "a5e0e301f67e24c03c0a425524f597cecf622a2269fe08b5e19c8067fd75185c", + "prompt_hash": "592147755b2d7ba3a08c2250fe8e92b6f5bcb55d24335546f2c01b5dd07f9b2d", "code_hash": "cca0497f63c1f43f3e8c9359f6a6fa7d0e8b3e9a5082aa911294907b7515b602", "example_hash": "9a7961a4044a54c46ce6c43c8adbbb83da46f233d9c6a9eaa28302440c0052c0", "test_hash": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1", @@ -10,7 +10,7 @@ "test_sync_main.py": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1" }, "include_deps": { - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", diff --git a/.pdd/meta/sync_orchestration_python.json b/.pdd/meta/sync_orchestration_python.json index 1f4cd0b4d1..929431b897 100644 --- a/.pdd/meta/sync_orchestration_python.json +++ b/.pdd/meta/sync_orchestration_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-09T22:54:16.600950+00:00", + "timestamp": "2026-07-10T02:29:20.942494+00:00", "command": "fix", - "prompt_hash": "8ecc2fda31b554402d09634c23a256f0e86770b837a47818a6e72af0444795d5", + "prompt_hash": "a1fb8c7390cb2118ffde37bd0257ae78e0af773778b16d588be66eaf8ecfb54a", "code_hash": "72a9e22929b3538e8c63915bf12568998d5ae1226d84b4518c6f4e460f06a2b6", "example_hash": "cc1313a948946026d418c85a07e5bf0eedeb5915c44d630440e489979755e1f7", "test_hash": "807987d709b08ea7064a727bfa536ffcd10441ec1742f4743e9a4c25b8f8a63f", @@ -11,7 +11,7 @@ }, "include_deps": { "docs/whitepaper.md": "3347db03fa35376024b59d8546efdf0858655746490561b88b710fa6b85017cc", - "README.md": "4ffb80692de7472dea9b2d600852e08eab2e15b76a461fc83712eab10c0973af", + "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", diff --git a/README.md b/README.md index 556d52a4e2..45f0758489 100644 --- a/README.md +++ b/README.md @@ -3833,7 +3833,7 @@ Here are some common issues and their solutions: 9. **Sync-Specific Issues**: - **"Another sync is running"**: Check for stale locks in `.pdd/locks/` directory and remove if process no longer exists - **Complex conflict resolution problems**: Use `pdd --verbose sync --dry-run basename` to see detailed LLM reasoning and decision analysis - - **State corruption or unexpected behavior**: Delete `.pdd/meta/{basename}_{language}.json` to reset fingerprint state + - **State corruption or unexpected behavior**: Re-stamp the unit's fingerprint with `pdd reconcile {basename} --heal` (deterministic, no LLM). Do NOT hand-edit or delete `.pdd/meta/*.json` — the committed fingerprints are the drift oracle and must be regenerated, not edited (see CONTRIBUTING.md). - **Animation display issues**: Sync operations work in background; animation is visual feedback only and doesn't affect functionality - **Fingerprint mismatches**: Use `pdd sync --dry-run basename` to see what changes were detected and why operations were recommended diff --git a/architecture_waivers.json b/architecture_waivers.json index 2754c9beab..73bd845d40 100644 --- a/architecture_waivers.json +++ b/architecture_waivers.json @@ -99,6 +99,15 @@ "python_env_detector": "Host Python env detector; TODO add tests/test_python_env_detector.py.", "test_result": "shared test-command return type; TODO add tests/test_test_result.py.", "validate_prompt_includes": " validation/cleanup; TODO add tests/test_validate_prompt_includes.py." + }, + "commands_without_prompt": { + "_README": "Informational: pdd/commands/*.py CLI wrappers that are hand-written (no generating prompt), consistent with each other. Not enforced by the module<->entry bijection (that gate is scoped to top-level pdd/*.py). Listed so the gap is explicit, not silent (#1969 review nit).", + "resolve": "`pdd resolve` CONFLICT-finalization command; hand-written wrapper over sync_determine_operation/operation_log primitives, no generating prompt.", + "reconcile": "`pdd reconcile` deterministic fingerprint stamper; hand-written wrapper over continuous_sync, no generating prompt.", + "drift": "`pdd checkup drift` command wrapper; hand-written, no prompt.", + "coverage": "`pdd coverage` command wrapper; hand-written, no prompt.", + "extracts": "`pdd extracts` command wrapper; hand-written, no prompt.", + "checkup_snapshot": "`pdd checkup snapshot` command wrapper; hand-written, no prompt." } } } diff --git a/pdd/commands/resolve.py b/pdd/commands/resolve.py index cb67c4c6c1..67fc0214af 100644 --- a/pdd/commands/resolve.py +++ b/pdd/commands/resolve.py @@ -84,14 +84,66 @@ def _accept_current( paths: Dict[str, Path], as_json: bool, quiet: bool, + force: bool = False, ) -> int: """Stamp the current tree as the agreed baseline for the unit. + Only a CONFLICT (prompt AND a derived artifact both changed) is stampable by + default: ``--accept-current`` is a CONFLICT-resolution tool, not a general + drift silencer. Single-sided drift (code-only / prompt-only) must go through + ``pdd update`` / ``pdd sync`` so the stale side is actually reconciled, not + silently baselined away; ``--force`` overrides for the rare "accept current as + truth" case. + Transactional at the command level: it re-fingerprints, then re-classifies and only reports success when the unit lands IN_SYNC. Any other post-state is surfaced as a failure rather than a silent partial stamp. """ before_fp, before_changes, before_class = _classify(basename, language, paths) + if before_class == "IN_SYNC": + if as_json: + click.echo(json.dumps({ + "basename": basename, + "language": language, + "strategy": "accept-current", + "before": "IN_SYNC", + "after": "IN_SYNC", + "changed_files": [], + "resolved": True, + }, indent=2, sort_keys=True)) + elif not quiet: + click.echo(f"'{basename}' ({language}) is already in sync; nothing to resolve.") + return 0 + if before_class != "CONFLICT" and not force: + moved = ", ".join(before_changes) or "no tracked artifacts" + suffix = "" if language.lower() == "python" else f" --language {language}" + if before_class == "UNBASELINED": + guidance = f"`pdd reconcile {basename}{suffix} --backfill` to baseline it" + else: # DRIFT — single-sided (code-only or prompt-only) + guidance = ( + f"`pdd update {basename}{suffix}` (back-propagate code->prompt) or " + f"`pdd sync {basename}{suffix}` (regenerate) to reconcile the stale " + f"side, or `pdd reconcile {basename}{suffix} --heal` to stamp only" + ) + if as_json: + click.echo(json.dumps({ + "basename": basename, + "language": language, + "strategy": "accept-current", + "before": before_class, + "changed_files": before_changes, + "resolved": False, + "error": "not-a-conflict", + }, indent=2, sort_keys=True)) + elif not quiet: + click.echo( + f"'{basename}' ({language}) is {before_class} ({moved}), not a CONFLICT. " + "--accept-current only resolves CONFLICTs (prompt AND code both changed " + f"since the last sync). Run {guidance}. Pass --force to stamp the current " + "tree as the baseline anyway.", + err=True, + ) + return 2 command = ( before_fp.command if before_fp is not None and before_fp.command in _SETTLED_COMMANDS @@ -181,6 +233,13 @@ def _preview_llm_strategy(basename: str, language: str, strategy: str) -> int: default=False, help="[preview] Back-propagate code into the prompt (not yet automated).", ) +@click.option( + "--force", + is_flag=True, + default=False, + help="Allow --accept-current on non-CONFLICT (single-sided) drift, stamping " + "the current tree as truth without reconciling the stale side.", +) @click.option( "--json", "as_json", @@ -196,6 +255,7 @@ def resolve( accept_current: bool, prompt_wins: bool, code_wins: bool, + force: bool, as_json: bool, ) -> None: # pylint: disable=too-many-arguments,too-many-positional-arguments @@ -242,5 +302,5 @@ def resolve( f"Run `pdd sync` to see tracked units." ) raise click.exceptions.Exit( - _accept_current(basename, language, paths, as_json, quiet) + _accept_current(basename, language, paths, as_json, quiet, force) ) diff --git a/pdd/prompts/sync_determine_operation_python.prompt b/pdd/prompts/sync_determine_operation_python.prompt index 585fc26dae..1698240239 100644 --- a/pdd/prompts/sync_determine_operation_python.prompt +++ b/pdd/prompts/sync_determine_operation_python.prompt @@ -34,7 +34,7 @@ You are an expert Python developer. Your task is to implement the core decision- 4. Coverage gaps → `test_extend` (Python only) or `all_synced` (non-Python, since coverage tooling is Python-specific). When `PDD_DISABLE_TEST_EXTEND` is truthy (`1`, `true`, `yes`, or `on`, case-insensitive), Python coverage gaps MUST also return the existing `all_synced` no-op shape with `test_extend_skipped: True` and a skip reason citing the disabled `test_extend` guard instead of returning `test_extend`. This suppression affects only coverage-driven `test_extend`; all other operation priorities remain unchanged. 5. Missing derived files → code → example → test (respecting `skip_tests`/`skip_verify` flags). 6. Isolated replay/repair override → when `isolated_replay_or_repair=True`, missing or stale examples must not preempt code replay/repair decisions. Existing examples may be read as context, but the decision engine must not schedule `example` unless the caller explicitly requested example regeneration. - 7. Conflict: prompt + derived files both changed → return `fail_and_request_manual_merge` with `details['classification'] == 'CONFLICT'`. The `reason` must be actionable on its own — it names the unit, states which artifacts moved, and gives the exact resolution commands (`pdd resolve --accept-current` / `--prompt-wins` / `--code-wins`, with a `--language` suffix for non-Python units) — and `details` carries `basename`, `language`, `changed_files`, and a `resolution_commands` map. Preserve the existing fingerprint and run-report in both mutable and read-only/log analysis; do not delete metadata, re-run fresh analysis, or choose either the prompt or derived artifact as the winner. Derived-only changes → `verify` or `test` (not a conflict). + 7. Conflict: prompt + derived files both changed → return `fail_and_request_manual_merge` with `details['classification'] == 'CONFLICT'`. The `reason` must be actionable on its own — it names the unit, states which artifacts moved, and gives the exact resolution commands: `pdd resolve --accept-current` (finalize a hand-merge, deterministic) plus the real LLM commands that let one side win — `pdd update ` (code-wins: back-propagate code into the prompt) and `pdd sync ` (prompt-wins: regenerate code from the prompt), with a `--language` suffix for non-Python units. Do NOT advertise `pdd resolve --prompt-wins` / `--code-wins` in the reason: those flags are non-automated previews, so point at the runnable commands instead (#1969 review finding 3). `details` carries `basename`, `language`, `changed_files`, and a `resolution_commands` map (keys `accept_current`, `prompt_wins`→`pdd sync`, `code_wins`→`pdd update`). Preserve the existing fingerprint and run-report in both mutable and read-only/log analysis; do not delete metadata, re-run fresh analysis, or choose either the prompt or derived artifact as the winner. Derived-only changes → `verify` or `test` (not a conflict). 4. **Skip Flags**: `skip_tests` and `skip_verify` parameters flow through `sync_determine_operation`, `_is_workflow_complete`, and `_handle_missing_expected_files`. When `skip_tests=True`, low coverage returns `all_synced` instead of `test`/`test_extend`. When both `skip_tests=True` and `skip_verify=True`, workflow completion requires only the prompt/code/example file set and must not require run reports, test reports, or verification fingerprints. Stale or failing cached test-results from `run_report` must be ignored (do not recommend `fix` or `crash`) when `skip_tests` is active. 5. **Context Override**: All path-resolving functions accept `context_override` to select a specific `.pddrc` context. `_relative_basename_for_context` strips context-specific prefixes from basenames for template expansion. For prompts_dir values, extract the prefix after the 'prompts/' segment wherever it appears in the path (e.g., 'prompts/frontend' → 'frontend', 'extensions/app/prompts/frontend' → 'frontend'). Use `_extract_prefix_from_prompts_dir()` from `construct_paths` for this. 6. **Path Resolution (Issue #237, #1169, #1303)**: Use `construct_paths` for configuration-aware pathing. If `.pddrc` has an `outputs` template section, use `_generate_paths_from_templates`. `_resolve_prompts_root` resolves prompts_dir relative to `.pddrc` location. Case-insensitive prompt file lookups must return the actual on-disk filename casing even when a lowercased candidate path reports `exists()` on case-insensitive filesystems. When the constructed prompt path does not exist, `_find_prompt_file` searches recursively through `prompts_root` subdirectories for a case-insensitive filename match (both basename and language suffix are case-insensitive). When multiple nested files share the basename, `context_override` scopes to the correct `.pddrc` context subdirectory, then basename directory hints disambiguate, then ties are broken by shallowest path-part count then lexicographic order. This ensures prompts in nested directories (e.g., `prompts/src/clients/firestore_client_Python.prompt`) are found even when `get_pdd_file_paths` is called with a flat basename and lowercase language. `_resolve_prompt_path_from_architecture` also performs a recursive case-insensitive search when its naively-joined path does not exist on disk. When architecture.json supplies a `filepath`, use the basename-resolved `.pddrc` context for example/test directories rather than cwd/default context, so repos with context-specific examples (e.g., `context/`, `context/commands/`) do not drift to `examples/`. When the prompt file does not exist yet (new module creation), `.pddrc` context's `prompts_dir` prefix is applied to the fallback path. diff --git a/pdd/sync_determine_operation.py b/pdd/sync_determine_operation.py index 0ed51f2567..8929820cba 100644 --- a/pdd/sync_determine_operation.py +++ b/pdd/sync_determine_operation.py @@ -2033,12 +2033,19 @@ def _describe_conflict_artifacts(changes: List[str]) -> str: def _conflict_resolution_commands(basename: str, language: str) -> Dict[str, str]: - """Exact `pdd resolve` commands offered for a CONFLICT unit.""" + """Exact commands offered for a CONFLICT unit — all runnable today. + + ``accept_current`` finalizes a hand-merge deterministically; ``prompt_wins`` / + ``code_wins`` are the real LLM commands (``pdd sync`` / ``pdd update``) that let + one side win. (The ``pdd resolve --prompt-wins`` / ``--code-wins`` flags are + only non-automated previews of these, so the message points at the real + commands rather than the preview stubs.) + """ suffix = _conflict_command_suffix(language) return { "accept_current": f"pdd resolve {basename}{suffix} --accept-current", - "prompt_wins": f"pdd resolve {basename}{suffix} --prompt-wins", - "code_wins": f"pdd resolve {basename}{suffix} --code-wins", + "prompt_wins": f"pdd sync {basename}{suffix}", + "code_wins": f"pdd update {basename}{suffix}", } @@ -2071,11 +2078,12 @@ def _prompt_derived_conflict_decision( moved = _describe_conflict_artifacts(changes) reason = ( f"CONFLICT: '{basename}' — {moved} changed since the last sync, so pdd " - f"will not auto-pick a winner (that would discard your edits). Resolve with " - f"`{resolution_commands['accept_current']}` (keep the current files as the new " - f"baseline), `{resolution_commands['prompt_wins']}` (regenerate code from the " - f"prompt), or `{resolution_commands['code_wins']}` (back-propagate the code " - f"into the prompt)." + f"will not auto-pick a winner (that would discard your edits). After hand-" + f"merging, run `{resolution_commands['accept_current']}` to record the current " + f"files as the new baseline. To let one side win instead, run " + f"`{resolution_commands['code_wins']}` (back-propagate the code into the " + f"prompt) or `{resolution_commands['prompt_wins']}` (regenerate the code from " + f"the prompt)." ) return SyncDecision( operation='fail_and_request_manual_merge', diff --git a/tests/test_resolve_command.py b/tests/test_resolve_command.py index b5b01825ce..3cf9fe2a67 100644 --- a/tests/test_resolve_command.py +++ b/tests/test_resolve_command.py @@ -77,6 +77,65 @@ def _make_conflict_unit(base: Path) -> Tuple[str, str, Path]: return BASENAME, LANGUAGE, fp_path +def _make_code_only_drift_unit(base: Path) -> Tuple[str, str, Path]: + """Create a synced unit then edit ONLY the code -> single-sided DRIFT (not CONFLICT).""" + _make_conflict_unit(base) + fp_path = base / ".pdd" / "meta" / f"{BASENAME}_{LANGUAGE}.json" + paths = get_pdd_file_paths(BASENAME, LANGUAGE, prompts_dir="prompts") + # Re-sync by stamping current, then edit only the code so the prompt is unchanged. + runner = CliRunner() + runner.invoke(resolve, [BASENAME, "--accept-current"], obj={}) + _write(Path(paths["code"]), "def value():\n return 99\n") + return BASENAME, LANGUAGE, fp_path + + +def test_accept_current_refuses_code_only_drift(tmp_path): + """#1969 review finding 2: --accept-current must NOT silently baseline single-sided + drift; it directs the user to pdd update / pdd sync instead and does not stamp.""" + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + base = Path(tmp) + _make_code_only_drift_unit(base) + paths = get_pdd_file_paths(BASENAME, LANGUAGE, prompts_dir="prompts") + before = read_fingerprint(BASENAME, LANGUAGE, paths=paths) + + result = runner.invoke(resolve, [BASENAME, "--accept-current"], obj={}) + + assert result.exit_code == 2, result.output + assert "not a CONFLICT" in result.output + assert "pdd update" in result.output and "pdd sync" in result.output + # Fingerprint is NOT changed by the refused resolve. + after = read_fingerprint(BASENAME, LANGUAGE, paths=paths) + assert after.code_hash == before.code_hash + + +def test_force_stamps_code_only_drift(tmp_path): + """--force is the explicit escape hatch to accept current-as-truth on drift.""" + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + base = Path(tmp) + _make_code_only_drift_unit(base) + paths = get_pdd_file_paths(BASENAME, LANGUAGE, prompts_dir="prompts") + current = calculate_sha256(Path(paths["code"])) + + result = runner.invoke(resolve, [BASENAME, "--accept-current", "--force"], obj={}) + + assert result.exit_code == 0, result.output + after = read_fingerprint(BASENAME, LANGUAGE, paths=paths) + assert after.code_hash == current + + +def test_accept_current_noop_when_already_in_sync(tmp_path): + runner = CliRunner() + with runner.isolated_filesystem() as tmp: + base = Path(tmp) + _make_conflict_unit(base) + runner.invoke(resolve, [BASENAME, "--accept-current"], obj={}) # -> IN_SYNC + result = runner.invoke(resolve, [BASENAME, "--accept-current"], obj={}) + assert result.exit_code == 0, result.output + assert "already in sync" in result.output + + def test_accept_current_resolves_conflict_to_in_sync(): runner = CliRunner() with runner.isolated_filesystem() as tmp: diff --git a/tests/test_sync_determine_operation.py b/tests/test_sync_determine_operation.py index 0d1144f2e3..64a30a65b1 100644 --- a/tests/test_sync_determine_operation.py +++ b/tests/test_sync_determine_operation.py @@ -1143,15 +1143,19 @@ def test_conflict_message_is_actionable(pdd_test_environment): assert BASENAME in decision.reason assert "prompt" in decision.reason and "code" in decision.reason assert f"pdd resolve {BASENAME} --accept-current" in decision.reason - assert f"pdd resolve {BASENAME} --prompt-wins" in decision.reason - assert f"pdd resolve {BASENAME} --code-wins" in decision.reason + # The message points at the REAL runnable commands, not the preview stubs + # (#1969 review finding 3: --prompt-wins/--code-wins are non-automated stubs). + assert f"pdd sync {BASENAME}" in decision.reason + assert f"pdd update {BASENAME}" in decision.reason + assert "--prompt-wins" not in decision.reason + assert "--code-wins" not in decision.reason # Structured details for machine consumers (CI summaries, drift ledger). assert decision.details["basename"] == BASENAME assert decision.details["language"] == LANGUAGE commands = decision.details["resolution_commands"] assert commands["accept_current"] == f"pdd resolve {BASENAME} --accept-current" - assert commands["prompt_wins"] == f"pdd resolve {BASENAME} --prompt-wins" - assert commands["code_wins"] == f"pdd resolve {BASENAME} --code-wins" + assert commands["prompt_wins"] == f"pdd sync {BASENAME}" + assert commands["code_wins"] == f"pdd update {BASENAME}" def test_conflict_decision_helper_formats_language_suffix_and_artifacts(): @@ -1166,7 +1170,7 @@ def test_conflict_decision_helper_formats_language_suffix_and_artifacts(): ) commands = decision.details["resolution_commands"] assert commands["accept_current"] == "pdd resolve parser --language javascript --accept-current" - assert commands["code_wins"] == "pdd resolve parser --language javascript --code-wins" + assert commands["code_wins"] == "pdd update parser --language javascript" assert "prompt, code, and test changed" in decision.reason assert decision.details["read_only"] is True # Non-destructive contract holds regardless of language. From 4df2f96e6f32d4925cd20129b7a13c63e65de051 Mon Sep 17 00:00:00 2001 From: Serhan Date: Thu, 9 Jul 2026 19:51:13 -0700 Subject: [PATCH 30/30] Address #1969 review pass 2: valid non-Python commands, README backfill, reconcile no-match guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finding 1: the CONFLICT message and pdd resolve guidance emitted invalid commands for non-Python units — pdd sync/pdd update/pdd reconcile reject --language (only pdd resolve accepts it), and pdd update takes the CODE FILE path, not a basename. Fixed all sites (sync_determine_operation conflict message, resolve.py guard + stub previews) to emit valid shapes; tests lock in no-suffix sync/update + code-path. Finding 2: README recovery advice said 'pdd reconcile --heal', but a deleted/ invalid fingerprint is UNBASELINED and only --backfill stamps it; --heal leaves it broken. README now points at --backfill (missing/invalid) vs --heal (drifted). Finding 3: 'pdd reconcile --check' exited 0/ok:true with 0 units, so CI/ runbook checks could silently skip the intended unit. A targeted run that matches no unit now errors (nonzero) with a spelling hint. New test covers it. Restamped; gates + resolve/sync/continuous_sync/orchestration suites + lint green. Co-Authored-By: Claude Fable 5 --- .pdd/meta/auto_deps_main_python.json | 6 ++--- .pdd/meta/cmd_test_main_python.json | 6 ++--- .pdd/meta/commands_maintenance_python.json | 6 ++--- .pdd/meta/commands_misc_python.json | 6 ++--- .pdd/meta/commands_templates_python.json | 6 ++--- .pdd/meta/commands_utility_python.json | 6 ++--- .pdd/meta/construct_paths_python.json | 6 ++--- .pdd/meta/core_dump_python.json | 6 ++--- .pdd/meta/core_errors_python.json | 6 ++--- .pdd/meta/core_utils_python.json | 6 ++--- .pdd/meta/detect_change_main_python.json | 6 ++--- .pdd/meta/generate_output_paths_python.json | 6 ++--- .pdd/meta/metadata_sync_python.json | 6 ++--- .pdd/meta/pre_checkup_gate_python.json | 6 ++--- .pdd/meta/preprocess_main_python.json | 6 ++--- .pdd/meta/split_main_python.json | 6 ++--- .pdd/meta/sync_animation_python.json | 6 ++--- .../meta/sync_determine_operation_python.json | 8 +++--- .pdd/meta/sync_main_python.json | 6 ++--- .pdd/meta/sync_orchestration_python.json | 6 ++--- README.md | 2 +- pdd/commands/reconcile.py | 17 ++++++++++++- pdd/commands/resolve.py | 20 +++++++++------ pdd/sync_determine_operation.py | 25 +++++++++++++------ tests/test_continuous_sync.py | 17 +++++++++++++ tests/test_resolve_command.py | 5 +++- tests/test_sync_determine_operation.py | 18 ++++++++----- 27 files changed, 141 insertions(+), 85 deletions(-) diff --git a/.pdd/meta/auto_deps_main_python.json b/.pdd/meta/auto_deps_main_python.json index 5d126ea744..ee16ef01f9 100644 --- a/.pdd/meta/auto_deps_main_python.json +++ b/.pdd/meta/auto_deps_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.596677+00:00", + "timestamp": "2026-07-10T02:49:03.442689+00:00", "command": "fix", - "prompt_hash": "aa9941eb508dcdabb3055f678512805b3c3d15d9f593da5b974ad55d49cd53e1", + "prompt_hash": "891b3052d91d751f0a835ef56cb2cc56d7746d602f35c713327f18ade51b7cd2", "code_hash": "b5df06f550c4dc0151af20f911eb19552d494cfb9853a7f35bd67c096a40581a", "example_hash": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "test_hash": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20", @@ -10,7 +10,7 @@ "test_auto_deps_main.py": "315cb31e6727a0410054111f294d19e1897d7551b30f79536bdc4b1655750a20" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/insert_includes_example.py": "c304bf4656f75fa26192c92b3eb0422a903d8a1bc82dda3158dc9f184b337873", diff --git a/.pdd/meta/cmd_test_main_python.json b/.pdd/meta/cmd_test_main_python.json index 43329d1bd5..5ced2e7628 100644 --- a/.pdd/meta/cmd_test_main_python.json +++ b/.pdd/meta/cmd_test_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.647286+00:00", + "timestamp": "2026-07-10T02:49:03.495671+00:00", "command": "fix", - "prompt_hash": "aa1735966c2d592d9c58a2b848d99dd640cf6fc91cbb9123c67705e017e9cd7a", + "prompt_hash": "bcdd092301e52973cf761b409159fdc035a12de4b74caa554ce2010600d56ddc", "code_hash": "cc809a1c54c8f4aa2ac4dd9e391d89df4b4e1be2dacc42f0a71306b4a666cf3d", "example_hash": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "test_hash": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643", @@ -10,7 +10,7 @@ "test_cmd_test_main.py": "d940dca46c808464348228dba68d1f88a884ff9ea0d827ce9c4e8ef27e78d643" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/cloud_function_call.py": "62ac7724ce2e3eddbba2b743bd7aa5790dbed34eae01e77e0252c4cc6358c95e", diff --git a/.pdd/meta/commands_maintenance_python.json b/.pdd/meta/commands_maintenance_python.json index e65035f999..814d97572c 100644 --- a/.pdd/meta/commands_maintenance_python.json +++ b/.pdd/meta/commands_maintenance_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.683001+00:00", + "timestamp": "2026-07-10T02:49:03.529788+00:00", "command": "fix", - "prompt_hash": "0b65467c46b879918e96569280f2ea87954e0e5296c1f21bee94e45c0678007d", + "prompt_hash": "2a12b3738fd483e3af54be825ffad3fc76c224df0af7bf582dbd48161a9a94c3", "code_hash": "4fa2499fe14940b0bd6858ca665870236c8be4342b7d44514d920381616b980a", "example_hash": "89252d2bb50c54846397d3ec319aae9ce69434d2af7a6d746dd7d85a317216e6", "test_hash": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a", @@ -10,7 +10,7 @@ "test_maintenance.py": "8ec4ee78179bdd2988cb4e3ee74224a80234e3b84c01fe01059f493cdff06b8a" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/__init__example.py": "84208a445d03a336e465709ec0687eb969c8d865e6739bf8b79f2c8a8aad351a", "context/agentic_sync_example.py": "aa9683f1a26841f3cae854e72cce38636f0859d8dd2f7672fa14e412afdef884", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/commands_misc_python.json b/.pdd/meta/commands_misc_python.json index 35cf4c1e19..5f07cecc92 100644 --- a/.pdd/meta/commands_misc_python.json +++ b/.pdd/meta/commands_misc_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.686448+00:00", + "timestamp": "2026-07-10T02:49:03.532875+00:00", "command": "fix", - "prompt_hash": "c5d8227f587562836a2ccbced292c1c5db67522c39afbc00d086addbe4b9261f", + "prompt_hash": "1bf6621e4f05b8af703d8e23a3bc9aec758b5bfe6bb75cb3c20501136687f60a", "code_hash": "e49fff5cb806fc88e2ba5e54f445f2b2f855d6902946319c47a264ab6f13885c", "example_hash": "7d7985d21dd7b962257856cb92d13e26c016bc09ce14aaac4c68baaead97dc4b", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/preprocess_main_example.py": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/commands_templates_python.json b/.pdd/meta/commands_templates_python.json index a8ef18e697..d7b5f77e1e 100644 --- a/.pdd/meta/commands_templates_python.json +++ b/.pdd/meta/commands_templates_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.698902+00:00", + "timestamp": "2026-07-10T02:49:03.545362+00:00", "command": "fix", - "prompt_hash": "f1d5e36e3523c9524c2286efee6736f0c823f6b8a8cb99a993d305e63b823c69", + "prompt_hash": "1e639b0cb31c602f7d32c0aeba64ba166a8945b7eea4e6218c3ab585fdeaf284", "code_hash": "6cb72959c02bcb9df6c2661ed339d61a782f4466980c0f899371af2113818dd0", "example_hash": "017d7a9cbdec60dd67cee662f3b21a68638137cd086fb335ef92889e1d91b09a", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/commands_utility_python.json b/.pdd/meta/commands_utility_python.json index a56fad8713..9e19ec2b16 100644 --- a/.pdd/meta/commands_utility_python.json +++ b/.pdd/meta/commands_utility_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.703842+00:00", + "timestamp": "2026-07-10T02:49:03.549852+00:00", "command": "fix", - "prompt_hash": "425ea87acc63af610131c19858b2f58ce8a6348cdeeb063ed36c47ce14b4380e", + "prompt_hash": "e49fdb165f324559f702cf8cc9d6b2fb5f1ca98bccf16a2fdc5ad594a91b5f8a", "code_hash": "9d0f70da4a91baf636335b69168fff3806b48d8fa6bc6bf0ca8c910bf1f11559", "example_hash": "fb7389c0ec837b8b6ee481e2eda04800f565fe247643f5bb9922dd1dfdab984a", "test_hash": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31", @@ -10,7 +10,7 @@ "test_utility.py": "077383807291f4ba2f3b070b264441a322e6429ef6d3c2ac64d0b88694602c31" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/fix_verification_main_example.py": "6490f398aca6df47b1a95e46a4ecfc0aabe299b5022de5c31ebc436e1bc3e459", "context/install_completion_example.py": "999be17c0ce476845d7048a1a909ad425e60c298dbc7c74f51b596ef134a8aec", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/construct_paths_python.json b/.pdd/meta/construct_paths_python.json index ac0f87be1e..5ae37883e4 100644 --- a/.pdd/meta/construct_paths_python.json +++ b/.pdd/meta/construct_paths_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.717094+00:00", + "timestamp": "2026-07-10T02:49:03.562835+00:00", "command": "fix", - "prompt_hash": "474048402f0cc4beca9563ddedf25a08ab6e2d7b1027e4fe0f2c6f91d47eb9f1", + "prompt_hash": "ed06c69349c1f30998fc211c7092cd97d780ff400e21615432cc28120de61972", "code_hash": "7b42a002e4ecc27be4d517cbc07f1fc9425e795d4918714f382d2ed5ddd00eab", "example_hash": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "test_hash": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418", @@ -10,7 +10,7 @@ "test_construct_paths.py": "2144db1645d973f2df5f8867c515943c5a09e674b34569c016055e576fdf6418" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/generate_output_paths_example.py": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "context/get_extension_example.py": "def9c34c1416259a0a031a996b96aeff5e73a7012adff6af1cc557e74ba97cc8", "context/get_language_example.py": "8b09af25b96fa49e2dcf5ff307bbeb0bc83e84b64618971d393397772a2fafab", diff --git a/.pdd/meta/core_dump_python.json b/.pdd/meta/core_dump_python.json index f8a8e6f222..3b134826a9 100644 --- a/.pdd/meta/core_dump_python.json +++ b/.pdd/meta/core_dump_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.737243+00:00", + "timestamp": "2026-07-10T02:49:03.584508+00:00", "command": "fix", - "prompt_hash": "7742acf1b2b29d5a1ba372549023c3cb16c02c3969ce606cdb91e73ef9078f8b", + "prompt_hash": "376be364fe8bbd3891431153b43d76268f643ca91d9f4dfa0d0a4a5efad5fd7b", "code_hash": "658eb3a08930160339f1e5c73b9093b38ae4289191b4b63c7e92115b33728882", "example_hash": "0416a935ac490b958ceedfc6e68c7fbd7e383966374ba13ccf7ebfeaf8ad0803", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_errors_python.json b/.pdd/meta/core_errors_python.json index dabb0f06ac..12987e25ec 100644 --- a/.pdd/meta/core_errors_python.json +++ b/.pdd/meta/core_errors_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.741931+00:00", + "timestamp": "2026-07-10T02:49:03.589387+00:00", "command": "fix", - "prompt_hash": "6a7cc275f7672dc33af6101f135e93620e171e9057f645be2858906044ff3316", + "prompt_hash": "7a1e0ee32d7d77201cde7e56df13d7a18701a8fc52d6eb7cc7507458a40010e0", "code_hash": "8d6ab075c9667038bcd5c043ff888f3f531b179d6c1337fe806591a2ee4e708a", "example_hash": "b50dbf08aec028bd57a8fe74762bf92aee9a1fe953fb3d7db50cc686c72bfee3", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/core_utils_python.json b/.pdd/meta/core_utils_python.json index 86c50c9555..64a9539727 100644 --- a/.pdd/meta/core_utils_python.json +++ b/.pdd/meta/core_utils_python.json @@ -1,14 +1,14 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.745383+00:00", + "timestamp": "2026-07-10T02:49:03.592763+00:00", "command": "fix", - "prompt_hash": "cec19b8cdec7c25647fa3516a0bcab52d7cdbfdba2c2765dc1e21c8a4389c5a4", + "prompt_hash": "bc14dac8215a3279591bde6eb02b3725f409ecace594f7a1b85c49003be23000", "code_hash": "4386b3c9efd08ba0510aa80150b579f203fe9dbc32e047712599a34f55537191", "example_hash": "ecda9cd9c5910246e0f857eacacac6ec381eb531695e5a56670a9dd8c02c0ef1", "test_hash": null, "test_files": {}, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } } \ No newline at end of file diff --git a/.pdd/meta/detect_change_main_python.json b/.pdd/meta/detect_change_main_python.json index 22bb9ab422..f071e53f22 100644 --- a/.pdd/meta/detect_change_main_python.json +++ b/.pdd/meta/detect_change_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.752601+00:00", + "timestamp": "2026-07-10T02:49:03.600240+00:00", "command": "fix", - "prompt_hash": "2c51643743f8c06f81886d0df773e20ae8ef96f817cf29edb7ca8f4a08aad31b", + "prompt_hash": "89e195d121090da7aa59c3c52f1fe544799383feed0aab78542248c88f2c7aa6", "code_hash": "2ef7a1859b4195c37e441c7ec79c00cfdff81f68af80dc277a4ee88b586d923a", "example_hash": "ddc494709d127398004f53de58bede388692b2839a97b26668c55575369d9edd", "test_hash": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6", @@ -10,7 +10,7 @@ "test_detect_change_main.py": "59bf5094d1970406c4a1d4da3666532ad64bb71b8a15063172bd18626196a0e6" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", diff --git a/.pdd/meta/generate_output_paths_python.json b/.pdd/meta/generate_output_paths_python.json index 64aee8c8d2..7dcd20362d 100644 --- a/.pdd/meta/generate_output_paths_python.json +++ b/.pdd/meta/generate_output_paths_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.791670+00:00", + "timestamp": "2026-07-10T02:49:03.639873+00:00", "command": "fix", - "prompt_hash": "c99f2d991b831b176ec29b5d466bf1699ca8668d684c0373e802f5880a7a04bb", + "prompt_hash": "d0b48ec878fad98d3e05c5e3df796cd6b319146c996e7d57ceaa75a8fcabf92b", "code_hash": "13890fe1983e3554b58f67404ce3848b3e9e329c03cf661446ad9ef62a71b43e", "example_hash": "0f8a6384ebfe9dc3ea448a4df7b4f5ebf9aa9b714f67a4322437638700a4307f", "test_hash": "c0ed9c8db22f119f3849ee3e00d8bac35b8d67fc78dfcccc5d6fefc78d1f081a", @@ -11,7 +11,7 @@ "test_generate_output_paths_regression.py": "3763968e8dc0e661e6516520f9282776ae81f82d5207633926ccee6fd60d50ba" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/change/15/initial_cli.py": "b607c3e67702ad3bc5e61cc40ce85571e4ff09015de96016c8d7d56eb78b8c74" } diff --git a/.pdd/meta/metadata_sync_python.json b/.pdd/meta/metadata_sync_python.json index 4c9684c241..67fd00fdd2 100644 --- a/.pdd/meta/metadata_sync_python.json +++ b/.pdd/meta/metadata_sync_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.829381+00:00", + "timestamp": "2026-07-10T02:49:03.682670+00:00", "command": "fix", - "prompt_hash": "0ccbe8cdb8576ac8a3cea4df0d381d33e8ceb79ae9f113ec0596fb517c0b1192", + "prompt_hash": "8c833103e615b0ffefad1d36b1d22c8a6d9837f2d7f66aaec3e227b0d12cc328", "code_hash": "3afaa5a409e500b3f91aab33dacee33fae47447fba80a1702d65a33761261782", "example_hash": "704453b3386724eef225b61c48f2fe922e1a973ac211c494e1d955dd44bcca11", "test_hash": "82af9e0bff7550d1f9bf46f4c6e7f4792143565e4e228d1507976f6b9fbac5f6", @@ -14,6 +14,6 @@ "pdd/architecture_registry.py": "5722225846b9cc8189b410a78e5714b4f2916d5748271d27f6f738692429c309", "pdd/architecture_sync.py": "0e0ff74978f49d629f92365723ebbea0e7c70e6d5234ccfdafb1c8e09c110c11", "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", - "pdd/sync_determine_operation.py": "c3020b343e614a5c2532aa80b07d43d1c3f1ccc4d9ed33fdce6ade4258084b15" + "pdd/sync_determine_operation.py": "ef8e41ab61742b9d8eb8fd2b1ee1d4de415223e0eb56734b70dee0bdb30f4b30" } } \ No newline at end of file diff --git a/.pdd/meta/pre_checkup_gate_python.json b/.pdd/meta/pre_checkup_gate_python.json index 2998963c98..d103668dcb 100644 --- a/.pdd/meta/pre_checkup_gate_python.json +++ b/.pdd/meta/pre_checkup_gate_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.846988+00:00", + "timestamp": "2026-07-10T02:49:03.702526+00:00", "command": "fix", - "prompt_hash": "214ed43f7a8606403192cb8f85fe1a3a724da727ae925b9a7bb5823c1da01dd3", + "prompt_hash": "30924f51857c9aae17ade802b113868f992d850e7a04f6898b7620572c7cb32f", "code_hash": "9ff0bbaa18c82cf4da836126861c40936a4555b8ff972f4bceee370492f37ace", "example_hash": "82585fac9350c3436528870c0b1d7e64228e6903cc4b5d0a62a35edecb266906", "test_hash": "d22520612cce8bf31712ff999b5f5f45153ddcd63a4044eb82c220d4a8021f62", @@ -16,6 +16,6 @@ "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "pdd/checkup_gates.py": "b6086954a93e0495661e6ca39d96b3079b928d13308bf0fcd6a16b1e0b5f511c", "pdd/operation_log.py": "d6712703f752c2045cd11a5c144b67454bb80700b83bd4e4612e55d2107b6072", - "pdd/sync_determine_operation.py": "c3020b343e614a5c2532aa80b07d43d1c3f1ccc4d9ed33fdce6ade4258084b15" + "pdd/sync_determine_operation.py": "ef8e41ab61742b9d8eb8fd2b1ee1d4de415223e0eb56734b70dee0bdb30f4b30" } } \ No newline at end of file diff --git a/.pdd/meta/preprocess_main_python.json b/.pdd/meta/preprocess_main_python.json index 94b91bb34c..5cb1eb2f13 100644 --- a/.pdd/meta/preprocess_main_python.json +++ b/.pdd/meta/preprocess_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.851870+00:00", + "timestamp": "2026-07-10T02:49:03.707446+00:00", "command": "fix", - "prompt_hash": "0f7acb8c766d59a20a9ef3e0c74e70675bff4d92be019f62069081383778425b", + "prompt_hash": "0a339cd291b75846ab9ba8d63328b7bdef0a4b24764b5bc277f2e2282f466504", "code_hash": "a069c3a73be88d3e3e93d40fd66e482c69bfb56ab627d862da31585612ac203b", "example_hash": "dc4cf0483361ef94467d8936ceef30b54b62e61d658c916663407a8f142ec851", "test_hash": "0fa3887c7a4e2c3f051ce719117b8f07444da419b35363b9dff4a2b5ae0f17e9", @@ -11,7 +11,7 @@ "test_preprocess_main_pdd_tags.py": "abddfe41c460aa7dcd4186028134deb4eef0a85419a7f6f59869a274c25f7ee8" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", "context/architecture_sync_example.py": "b6158dbc7ca3fd32665528562225f6739ec521a071d845acab0f7caaea221ae0", diff --git a/.pdd/meta/split_main_python.json b/.pdd/meta/split_main_python.json index 514999afc6..e3255722eb 100644 --- a/.pdd/meta/split_main_python.json +++ b/.pdd/meta/split_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.902273+00:00", + "timestamp": "2026-07-10T02:49:03.763585+00:00", "command": "fix", - "prompt_hash": "b81b93b2a60f31599407949c1b17d496c725d38f76843b32d5040b32708a61ce", + "prompt_hash": "f75671b4aae840f964ea24e517984b5debf6765a00cfb82ada6747be9aef2d65", "code_hash": "381837b939069c6fef6c115caaefaa34c3103722de6ca95037ced13941edae75", "example_hash": "ced192fcbfbfda15b35bd2dad5bbf4b4888acb091084cf58326832d224a77661", "test_hash": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887", @@ -10,7 +10,7 @@ "test_split_main.py": "fbc89f592fccf464f1ea1f31f912861a00bd8789f18b2f2d310901e59d969887" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254", diff --git a/.pdd/meta/sync_animation_python.json b/.pdd/meta/sync_animation_python.json index d30e1d79b3..5efec8de61 100644 --- a/.pdd/meta/sync_animation_python.json +++ b/.pdd/meta/sync_animation_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.916920+00:00", + "timestamp": "2026-07-10T02:49:03.780928+00:00", "command": "fix", - "prompt_hash": "d49c350fbcaf20a01486aeb160b769f75aeef1af2a79616c2cd51f453e6a0c12", + "prompt_hash": "f5073703052cded4e199a33c4c1cb6ce37c6e2bcc9b87cd5c4bafb4d9dbdee39", "code_hash": "b9261a68d14049db76c89179f98ee1c45a073cc9a656607d447612e23f68e285", "example_hash": "5b6a8af940fe44241889a279c1a8d3c978fe0c6ec3afc648510d8e33ffa7b18c", "test_hash": "f76041e4a4e313d3005d5961e76c3b08bfc26549e498d341cefe31560c328ebd", @@ -13,7 +13,7 @@ "test_sync_animation_phases.py": "fa098d0dc0e6bb3f1f45863c1d01cf1a798fdcbaa3a402025aa241a39faef76c" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/logo_animation_example.py": "f32a5cc330235c3b61fb16ac62d3ae7531c7c6dbc11af077fc79054736f0944d", "context/python_preamble.prompt": "0388ed131bf986f8752e1bc4c81e4da0460cfe2908ec8c60b1314edbab768254" } diff --git a/.pdd/meta/sync_determine_operation_python.json b/.pdd/meta/sync_determine_operation_python.json index a10126d713..9e150aaded 100644 --- a/.pdd/meta/sync_determine_operation_python.json +++ b/.pdd/meta/sync_determine_operation_python.json @@ -1,13 +1,13 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.923759+00:00", + "timestamp": "2026-07-10T02:49:03.787539+00:00", "command": "fix", "prompt_hash": "8800e2a4bdc8a41cc66b6c1300d7d3907cd738766ff20311ea8d6f239aeecbcc", - "code_hash": "c3020b343e614a5c2532aa80b07d43d1c3f1ccc4d9ed33fdce6ade4258084b15", + "code_hash": "ef8e41ab61742b9d8eb8fd2b1ee1d4de415223e0eb56734b70dee0bdb30f4b30", "example_hash": "225d20ea0210bbf52650a9f424879ff495e574dd2411eb4b86592a6d06cf59a5", - "test_hash": "f6b580299672d687f1e45abae8be179c55f4a584bec57589de3ed7d13665e5c1", + "test_hash": "5ebd9f9a9c18a30e44193619a944ffbd4dc427274a79d98ee4eeaa1497d6da06", "test_files": { - "test_sync_determine_operation.py": "f6b580299672d687f1e45abae8be179c55f4a584bec57589de3ed7d13665e5c1" + "test_sync_determine_operation.py": "5ebd9f9a9c18a30e44193619a944ffbd4dc427274a79d98ee4eeaa1497d6da06" }, "include_deps": { "context/agentic_langtest_example.py": "dbc5c87dc1b75d3299dbfb67b17df1838f9ba2c9bdb457097df0832cea112c3f", diff --git a/.pdd/meta/sync_main_python.json b/.pdd/meta/sync_main_python.json index 92872f1c0e..6800314c50 100644 --- a/.pdd/meta/sync_main_python.json +++ b/.pdd/meta/sync_main_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.931566+00:00", + "timestamp": "2026-07-10T02:49:03.795086+00:00", "command": "fix", - "prompt_hash": "592147755b2d7ba3a08c2250fe8e92b6f5bcb55d24335546f2c01b5dd07f9b2d", + "prompt_hash": "09a082d96379107d0e0076310eadd4d617681dbcf139bde90c39705c1c521ae0", "code_hash": "cca0497f63c1f43f3e8c9359f6a6fa7d0e8b3e9a5082aa911294907b7515b602", "example_hash": "9a7961a4044a54c46ce6c43c8adbbb83da46f233d9c6a9eaa28302440c0052c0", "test_hash": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1", @@ -10,7 +10,7 @@ "test_sync_main.py": "30f5651c0868812dacc7141629dc7ba11afb6a4417e695e98c2f74c1dfa4d1d1" }, "include_deps": { - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/auth_service_example.py": "4b6d2c8c9e13d1edc0d9805ee0c07657494cbf31dffe2bb0029b72975674a8cf", "context/construct_paths_example.py": "412cb260650bcbd628fba647db917a8d32f8191df2e1c32cc22f22c0c11b1740", "context/ctx_obj_params.prompt": "829e2ab327e37b75afcd0dcf3893dcaec9012a89a1f6e5198ec7cfc0395d2782", diff --git a/.pdd/meta/sync_orchestration_python.json b/.pdd/meta/sync_orchestration_python.json index 929431b897..f47a1b6a58 100644 --- a/.pdd/meta/sync_orchestration_python.json +++ b/.pdd/meta/sync_orchestration_python.json @@ -1,8 +1,8 @@ { "pdd_version": "0.0.300.dev0", - "timestamp": "2026-07-10T02:29:20.942494+00:00", + "timestamp": "2026-07-10T02:49:03.806824+00:00", "command": "fix", - "prompt_hash": "a1fb8c7390cb2118ffde37bd0257ae78e0af773778b16d588be66eaf8ecfb54a", + "prompt_hash": "33db18386d74d066127d81053e0f4c0f73284584c77e29524a968a8d23b209f2", "code_hash": "72a9e22929b3538e8c63915bf12568998d5ae1226d84b4518c6f4e460f06a2b6", "example_hash": "cc1313a948946026d418c85a07e5bf0eedeb5915c44d630440e489979755e1f7", "test_hash": "807987d709b08ea7064a727bfa536ffcd10441ec1742f4743e9a4c25b8f8a63f", @@ -11,7 +11,7 @@ }, "include_deps": { "docs/whitepaper.md": "3347db03fa35376024b59d8546efdf0858655746490561b88b710fa6b85017cc", - "README.md": "5230b0d653e825820a786e0583dcb24b0c3e2e050098ba17b48a63d7035349a1", + "README.md": "20fa5b831d67be4650513b50015390462ef972943077b5c63faebaf91906d1f2", "context/auto_deps_main_example.py": "9b9c36c18d39494b6e31b46f6e4758c25135b6fa3d1672fbb7365844f7d2de04", "context/cmd_test_main_example.py": "0774984ee29f70407429f1eff4a1b76287715b7ddd6adf2bc149e874c9b844bb", "context/code_generator_main_example.py": "4b66f24a1e2ac4195255738566b0cccdac0971523a245d3a8b78ad45d9e1a872", diff --git a/README.md b/README.md index 45f0758489..b3d7656819 100644 --- a/README.md +++ b/README.md @@ -3833,7 +3833,7 @@ Here are some common issues and their solutions: 9. **Sync-Specific Issues**: - **"Another sync is running"**: Check for stale locks in `.pdd/locks/` directory and remove if process no longer exists - **Complex conflict resolution problems**: Use `pdd --verbose sync --dry-run basename` to see detailed LLM reasoning and decision analysis - - **State corruption or unexpected behavior**: Re-stamp the unit's fingerprint with `pdd reconcile {basename} --heal` (deterministic, no LLM). Do NOT hand-edit or delete `.pdd/meta/*.json` — the committed fingerprints are the drift oracle and must be regenerated, not edited (see CONTRIBUTING.md). + - **State corruption or unexpected behavior**: Re-stamp the unit's fingerprint deterministically (no LLM) — use `pdd reconcile {basename} --backfill` to rebuild a missing/invalid fingerprint, or `pdd reconcile {basename} --heal` to re-stamp a drifted (but present) one. Run `pdd reconcile {basename}` first to see which state it's in. Do NOT hand-edit or delete `.pdd/meta/*.json` — the committed fingerprints are the drift oracle and must be regenerated, not edited (see CONTRIBUTING.md). - **Animation display issues**: Sync operations work in background; animation is visual feedback only and doesn't affect functionality - **Fingerprint mismatches**: Use `pdd sync --dry-run basename` to see what changes were detected and why operations were recommended diff --git a/pdd/commands/reconcile.py b/pdd/commands/reconcile.py index 8965ab4760..2b8098c448 100644 --- a/pdd/commands/reconcile.py +++ b/pdd/commands/reconcile.py @@ -10,7 +10,13 @@ import click -from ..continuous_sync import CheckResult, build_report, project_root, run_check +from ..continuous_sync import ( + CheckResult, + build_report, + project_root, + resolve_units, + run_check, +) def _pre_commit_hook_path(root: Path) -> Path: @@ -168,6 +174,15 @@ def reconcile( target = basename or module_name modules = [target] if target else None + # A targeted run that matches no unit must fail loudly, not silently pass with + # 0 units (#1969 review pass 2 finding 3: a typo'd basename would otherwise + # exit 0 / ok:true and skip the intended unit in CI/runbook checks). + if target is not None and not resolve_units(project_root(), modules=modules): + raise click.ClickException( + f"No PDD unit matches '{target}'. Run `pdd reconcile` (no argument) to " + "verify all units, or check the basename / --module spelling." + ) + if check: result = run_check(modules=modules) _emit_check(result, as_json) diff --git a/pdd/commands/resolve.py b/pdd/commands/resolve.py index 67fc0214af..91e15d6bbc 100644 --- a/pdd/commands/resolve.py +++ b/pdd/commands/resolve.py @@ -116,14 +116,16 @@ def _accept_current( return 0 if before_class != "CONFLICT" and not force: moved = ", ".join(before_changes) or "no tracked artifacts" - suffix = "" if language.lower() == "python" else f" --language {language}" + # Only `pdd resolve` takes --language; pdd sync/update/reconcile do not, and + # `pdd update` targets the code FILE path (#1969 review pass 2 finding 1). + code_target = str(paths.get("code")) if paths.get("code") else basename if before_class == "UNBASELINED": - guidance = f"`pdd reconcile {basename}{suffix} --backfill` to baseline it" + guidance = f"`pdd reconcile {basename} --backfill` to baseline it" else: # DRIFT — single-sided (code-only or prompt-only) guidance = ( - f"`pdd update {basename}{suffix}` (back-propagate code->prompt) or " - f"`pdd sync {basename}{suffix}` (regenerate) to reconcile the stale " - f"side, or `pdd reconcile {basename}{suffix} --heal` to stamp only" + f"`pdd update {code_target}` (back-propagate code->prompt) or " + f"`pdd sync {basename}` (regenerate) to reconcile the stale side, or " + f"`pdd reconcile {basename} --heal` to stamp only" ) if as_json: click.echo(json.dumps({ @@ -184,12 +186,16 @@ def _accept_current( def _preview_llm_strategy(basename: str, language: str, strategy: str) -> int: """Print what a not-yet-automated LLM strategy WOULD run; return non-zero.""" + # pdd sync takes a bare basename; pdd update takes the code file path; neither + # accepts --language (#1969 review pass 2 finding 1). Only `pdd resolve` does. suffix = "" if language.lower() == "python" else f" --language {language}" if strategy == "prompt-wins": - would_run = f"pdd sync {basename}{suffix}" + would_run = f"pdd sync {basename}" effect = "regenerate the code from the prompt (an LLM generation)" else: # code-wins - would_run = f"pdd update {basename}{suffix}" + paths = _resolve_paths(basename, language) + code_target = str(paths["code"]) if paths and paths.get("code") else basename + would_run = f"pdd update {code_target}" effect = "back-propagate the code into the prompt (an LLM update)" click.echo( f"--{strategy} would run `{would_run}` to {effect}, then re-stamp the " diff --git a/pdd/sync_determine_operation.py b/pdd/sync_determine_operation.py index 8929820cba..90ea6c2e75 100644 --- a/pdd/sync_determine_operation.py +++ b/pdd/sync_determine_operation.py @@ -2032,20 +2032,27 @@ def _describe_conflict_artifacts(changes: List[str]) -> str: return ", ".join(ordered[:-1]) + f", and {ordered[-1]}" -def _conflict_resolution_commands(basename: str, language: str) -> Dict[str, str]: +def _conflict_resolution_commands( + basename: str, language: str, code_path: Optional[Path] = None +) -> Dict[str, str]: """Exact commands offered for a CONFLICT unit — all runnable today. ``accept_current`` finalizes a hand-merge deterministically; ``prompt_wins`` / - ``code_wins`` are the real LLM commands (``pdd sync`` / ``pdd update``) that let - one side win. (The ``pdd resolve --prompt-wins`` / ``--code-wins`` flags are - only non-automated previews of these, so the message points at the real - commands rather than the preview stubs.) + ``code_wins`` are the real commands (``pdd sync`` / ``pdd update``) that let one + side win. (The ``pdd resolve --prompt-wins`` / ``--code-wins`` flags are only + non-automated previews of these, so the message points at the real commands.) + + Command-shape matters (#1969 review, pass 2): only ``pdd resolve`` accepts + ``--language``. ``pdd sync`` takes a bare basename (it syncs every language + variant of it) and ``pdd update`` takes the CODE FILE path — neither accepts a + ``--language`` suffix, so they must not get one. """ suffix = _conflict_command_suffix(language) + code_target = str(code_path) if code_path else f"path/to/{basename} code file" return { "accept_current": f"pdd resolve {basename}{suffix} --accept-current", - "prompt_wins": f"pdd sync {basename}{suffix}", - "code_wins": f"pdd update {basename}{suffix}", + "prompt_wins": f"pdd sync {basename}", + "code_wins": f"pdd update {code_target}", } @@ -2074,7 +2081,9 @@ def _prompt_derived_conflict_decision( safe_bn = _safe_basename(basename) fp_path = meta_dir / f"{safe_bn}_{language.lower()}.json" rr_path = meta_dir / f"{safe_bn}_{language.lower()}_run.json" - resolution_commands = _conflict_resolution_commands(basename, language) + resolution_commands = _conflict_resolution_commands( + basename, language, code_path=paths.get("code") if paths else None + ) moved = _describe_conflict_artifacts(changes) reason = ( f"CONFLICT: '{basename}' — {moved} changed since the last sync, so pdd " diff --git a/tests/test_continuous_sync.py b/tests/test_continuous_sync.py index 79a6c95ccd..b14302bc00 100644 --- a/tests/test_continuous_sync.py +++ b/tests/test_continuous_sync.py @@ -295,3 +295,20 @@ def test_cli_json_basename(tmp_path, monkeypatch): payload = json.loads(result.output) assert [u["basename"] for u in payload["units"]] == ["alpha"] assert payload["units"][0]["status"] == "current" + + +def test_cli_no_match_target_errors(tmp_path, monkeypatch): + """A targeted reconcile that matches no unit must FAIL, not silently pass with 0 + units (#1969 review pass 2 finding 3 — a typo would otherwise exit 0 / ok:true).""" + root = _make_repo(tmp_path) + _write_unit(root, "alpha") + cs.stamp_units(cs.resolve_units(root), root) + monkeypatch.chdir(root) + + for args in (["definitely_not_a_unit", "--check"], ["definitely_not_a_unit", "--check", "--json"]): + result = CliRunner().invoke(reconcile, args) + assert result.exit_code != 0, result.output + assert "No PDD unit matches" in result.output + # A real target still works. + ok = CliRunner().invoke(reconcile, ["alpha", "--check"]) + assert ok.exit_code == 0, ok.output diff --git a/tests/test_resolve_command.py b/tests/test_resolve_command.py index 3cf9fe2a67..32520aba8a 100644 --- a/tests/test_resolve_command.py +++ b/tests/test_resolve_command.py @@ -209,7 +209,10 @@ def test_code_wins_is_a_documented_stub_that_exits_nonzero(): assert result.exit_code == 2 assert "not yet automated" in result.output - assert "pdd update widget" in result.output + # code-wins previews `pdd update ` (pdd update takes a file, + # not a basename — #1969 review pass 2 finding 1). + assert "pdd update " in result.output + assert f"{BASENAME}.py" in result.output def test_stub_previews_do_not_mutate_the_fingerprint(): diff --git a/tests/test_sync_determine_operation.py b/tests/test_sync_determine_operation.py index 64a30a65b1..f99359de8d 100644 --- a/tests/test_sync_determine_operation.py +++ b/tests/test_sync_determine_operation.py @@ -1144,9 +1144,10 @@ def test_conflict_message_is_actionable(pdd_test_environment): assert "prompt" in decision.reason and "code" in decision.reason assert f"pdd resolve {BASENAME} --accept-current" in decision.reason # The message points at the REAL runnable commands, not the preview stubs - # (#1969 review finding 3: --prompt-wins/--code-wins are non-automated stubs). + # (#1969 review finding 3), with valid command shapes: pdd sync takes a bare + # basename and pdd update takes the code file path (review pass 2, finding 1). assert f"pdd sync {BASENAME}" in decision.reason - assert f"pdd update {BASENAME}" in decision.reason + assert f"pdd update {paths['code']}" in decision.reason assert "--prompt-wins" not in decision.reason assert "--code-wins" not in decision.reason # Structured details for machine consumers (CI summaries, drift ledger). @@ -1155,22 +1156,27 @@ def test_conflict_message_is_actionable(pdd_test_environment): commands = decision.details["resolution_commands"] assert commands["accept_current"] == f"pdd resolve {BASENAME} --accept-current" assert commands["prompt_wins"] == f"pdd sync {BASENAME}" - assert commands["code_wins"] == f"pdd update {BASENAME}" + assert commands["code_wins"] == f"pdd update {paths['code']}" def test_conflict_decision_helper_formats_language_suffix_and_artifacts(): - """Non-Python units get a --language suffix; 3-way co-edits read naturally.""" + """Non-Python units: only `pdd resolve` takes --language; sync/update must not + (#1969 review pass 2 finding 1 — sync/update reject --language).""" decision = _prompt_derived_conflict_decision( basename="parser", language="javascript", changes=["prompt", "code", "test"], - paths={}, + paths={"code": Path("src/parser.js")}, fingerprint=None, read_only=True, ) commands = decision.details["resolution_commands"] assert commands["accept_current"] == "pdd resolve parser --language javascript --accept-current" - assert commands["code_wins"] == "pdd update parser --language javascript" + assert commands["prompt_wins"] == "pdd sync parser" + assert commands["code_wins"] == "pdd update src/parser.js" + # sync/update reject --language; the message must never emit it for them. + assert "--language" not in commands["prompt_wins"] + assert "--language" not in commands["code_wins"] assert "prompt, code, and test changed" in decision.reason assert decision.details["read_only"] is True # Non-destructive contract holds regardless of language.