Skip to content

feat: add recommendation pipeline contract#514

Merged
nash87 merged 8 commits into
mainfrom
t-6318-recommendation-engine-contract
May 21, 2026
Merged

feat: add recommendation pipeline contract#514
nash87 merged 8 commits into
mainfrom
t-6318-recommendation-engine-contract

Conversation

@nash87
Copy link
Copy Markdown
Owner

@nash87 nash87 commented May 19, 2026

Adds the ParkHub PHP recommendation pipeline contract: a deterministic
weighted_v1 baseline plus a guarded fop_pipeline_v1 adapter configuration.

Scope

  • Adds the shared weighted_v1 recommendation contract, fixture, and static
    contract gate.
  • Adds fop_pipeline_v1 adapter configuration with mandatory weighted_v1
    fallback.
  • Keeps adapter use behind endpoint allowlisting, timeout policy, safe-mode
    behavior, and explicit configuration.
  • Adds recommendation contract/status evidence so the PHP runtime stays aligned
    with the Rust contract.
  • Documents the fop legal review packet boundary. fop legal is reference-only:
    attorney review, citation verification, deployment-specific configuration
    review, human signoff, and final legal judgment remain required.
  • Wires the recommendation contract gate into GitHub, Gitea, and local
    make/pre-push review paths.

Verification

  • fop/local-ci/pr: success on
    45e06c764584f531a9489ce2642c6439ee62d022.
  • GitHub required checks are green, including Required checks,
    fop local CI attestation, Dependency Review, Composer Audit,
    npm Audit, Schemathesis, Secret scan, Zizmor, and OSV-Scanner.
  • Native squash auto-merge is enabled.

Review Boundary

This PR ships the contract and guarded integration boundary. It does not enable
unreviewed automated decision support by default and does not claim legal
compliance for a live deployment. Production enablement still needs endpoint
policy, health/status monitoring, rollback switch, privacy/legal review, and
operator signoff in the release packet.

Remaining Blocker

Branch protection is blocked only by the required eligible review. After review
approval, native auto-merge should merge the PR.

Copilot AI review requested due to automatic review settings May 19, 2026 19:05
@github-actions github-actions Bot added ci CI/CD pipeline php PHP backend and Composer changes docs labels May 19, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93bf949ac0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/Http/Controllers/Api/RecommendationController.php Outdated
Comment thread app/Http/Controllers/Api/RecommendationController.php
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Introduces a versioned recommendation contract and related safety gates to support deterministic weighted_v1 scoring and a guarded fop_pipeline_v1 adapter (with mandatory fallback), plus documentation/fixtures and CI enforcement.

Changes:

  • Adds a shared weighted_v1 fixture + contract documentation and enforces them via a new contract-gate script wired into CI and local tooling.
  • Updates the recommendation engine to load versioned config/weights, emit recommendation_id, and record a RecommendationServed audit envelope (including adapter/legal boundary).
  • Adds fop_pipeline_v1 adapter configuration + tests for success/fallback/endpoint allowlisting, and locks stats behind admin.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tests/Feature/RecommendationExtendedTest.php Adds coverage for recommendation_id, audit envelope, fixture parity, pipeline adapter behavior, and secured stats endpoint.
scripts/check-recommendation-contract.sh Adds a fixture-hash + grep-based “contract gate” enforced in CI and local runs.
routes/modules/recommendations.php Protects recommendation stats endpoint with admin middleware.
routes/modules/bookings.php Ensures recommendations endpoint is behind module:recommendations.
docs/recommendation-engine-fixtures/weighted_v1.basic.json Adds deterministic fixture to pin weighted_v1 scoring outputs.
docs/recommendation-engine-contract.md Documents scoring semantics, config boundary, pipeline adapter rules, audit/legal boundary expectations.
docs/openapi/php.json Updates OpenAPI snapshot for new stats response fields/structure.
config/recommendations.php Introduces versioned defaults/weights and guarded pipeline settings.
app/Services/ModuleRegistry.php Adds recommendations module config keys and JSON Schema constraints (algorithm, weights, pipeline config).
app/Http/Controllers/Api/RecommendationController.php Implements versioned engine config, pipeline adapter call with fallback, stats expansion, and audit logging.
Makefile Runs the recommendation contract gate as part of make ci.
.github/workflows/ci.yml Enforces recommendation contract gate in GitHub Actions CI.
.github/scripts/fop-local-ci.sh Runs recommendation contract gate in local CI script.
.gitea/workflows/ci.yaml Enforces recommendation contract gate in Gitea CI.
Comments suppressed due to low confidence (4)

docs/openapi/php.json:1

  • The OpenAPI snapshot encodes several constraints/types that don’t match the implementation: (1) algorithm is const: weighted_v1 even though config allows fop_pipeline_v1; (2) algorithm_adapter.status is const: weighted_v1 but the adapter returns values like succeeded, fallback_error, fallback_not_configured; (3) top_recommended_lots is typed as string but the controller returns an array of {lot_name, count} objects; and (4) total_recommendations_served is typed as string but the controller returns a number. This will mislead clients and/or break generated SDKs—update the schema to reflect the real response shapes (enums/oneOf where needed, and correct array/object typing).
    docs/openapi/php.json:1
  • The OpenAPI snapshot encodes several constraints/types that don’t match the implementation: (1) algorithm is const: weighted_v1 even though config allows fop_pipeline_v1; (2) algorithm_adapter.status is const: weighted_v1 but the adapter returns values like succeeded, fallback_error, fallback_not_configured; (3) top_recommended_lots is typed as string but the controller returns an array of {lot_name, count} objects; and (4) total_recommendations_served is typed as string but the controller returns a number. This will mislead clients and/or break generated SDKs—update the schema to reflect the real response shapes (enums/oneOf where needed, and correct array/object typing).
    docs/openapi/php.json:1
  • The OpenAPI snapshot encodes several constraints/types that don’t match the implementation: (1) algorithm is const: weighted_v1 even though config allows fop_pipeline_v1; (2) algorithm_adapter.status is const: weighted_v1 but the adapter returns values like succeeded, fallback_error, fallback_not_configured; (3) top_recommended_lots is typed as string but the controller returns an array of {lot_name, count} objects; and (4) total_recommendations_served is typed as string but the controller returns a number. This will mislead clients and/or break generated SDKs—update the schema to reflect the real response shapes (enums/oneOf where needed, and correct array/object typing).
    docs/openapi/php.json:1
  • The OpenAPI snapshot encodes several constraints/types that don’t match the implementation: (1) algorithm is const: weighted_v1 even though config allows fop_pipeline_v1; (2) algorithm_adapter.status is const: weighted_v1 but the adapter returns values like succeeded, fallback_error, fallback_not_configured; (3) top_recommended_lots is typed as string but the controller returns an array of {lot_name, count} objects; and (4) total_recommendations_served is typed as string but the controller returns a number. This will mislead clients and/or break generated SDKs—update the schema to reflect the real response shapes (enums/oneOf where needed, and correct array/object typing).

Comment thread app/Http/Controllers/Api/RecommendationController.php Outdated
Comment thread app/Http/Controllers/Api/RecommendationController.php Outdated
Comment thread app/Http/Controllers/Api/RecommendationController.php Outdated
Comment thread app/Services/ModuleRegistry.php
Comment thread app/Services/ModuleRegistry.php
Comment thread app/Services/ModuleRegistry.php Outdated
Comment thread app/Services/ModuleRegistry.php
Comment thread app/Http/Controllers/Api/RecommendationController.php Outdated
Comment thread scripts/check-recommendation-contract.sh Outdated
@nash87 nash87 changed the title Add recommendation pipeline contract feat: add recommendation pipeline contract May 19, 2026
@github-actions github-actions Bot added the security Security related issues label May 19, 2026
@nash87 nash87 enabled auto-merge (squash) May 19, 2026 21:23
@nash87 nash87 merged commit 1bcced3 into main May 21, 2026
30 checks passed
@nash87 nash87 deleted the t-6318-recommendation-engine-contract branch May 21, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci CI/CD pipeline docs php PHP backend and Composer changes security Security related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants