Skip to content

M7.2: add normalized solution metrics foundation - #14

Merged
sunpole merged 3 commits into
mainfrom
m7.2/0.7.0-alpha.2-solution-metrics
Jul 26, 2026
Merged

M7.2: add normalized solution metrics foundation#14
sunpole merged 3 commits into
mainfrom
m7.2/0.7.0-alpha.2-solution-metrics

Conversation

@sunpole

@sunpole sunpole commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Summary

Starts M7.2 (0.7.0-alpha.2) with a small, non-invasive foundation layer for normalized solution metrics.

Changes

  • Add src/solution-metrics.js with one normalized SolutionMetrics model.
  • Preserve explicit pricing ready / pricing incomplete states.
  • Do not invent default pricing: incomplete pricing keeps BYN cost fields as null.
  • Add createDecisionSolution() adapter so pricing-ready normalized metrics can feed the existing M7.1 lexicographic ranking.
  • Add tests/solution-metrics.test.js covering incomplete pricing, ready BYN costing, refusal to rank missing prices, and cost-first ranking.
  • Add src/solution-metrics.js to npm run check:source.

Safety

  • Does not change sheet geometry, imposition generation, PDF output, published data, or existing M7.1 demo behavior.
  • Keeps M7.1 decision-profile ranking unchanged and only adds an adapter for normalized metrics.
  • Keeps prices operator-provided; no fake production defaults are introduced.

M7.2 scope alignment

This is the first M7.2 patch toward a unified metrics model for manual, paper-minimum, and future alternatives, plus explicit pricing readiness before pricing-based decisions.

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

Copy link
Copy Markdown

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: b811de1616

ℹ️ 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 src/solution-metrics.js

function pricingStatusFromCost(productionCost) {
if (!productionCost) return PRICING_STATUS.INCOMPLETE;
if (Number.isFinite(Number(productionCost.estimatedTotalCost))) return PRICING_STATUS.READY;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep null total costs in the incomplete state

When an incomplete cost object has estimatedTotalCost: null, Number(null) evaluates to 0, so the solution is marked pricing ready, normalized with a zero total, and accepted by createDecisionSolution(). Such a candidate can incorrectly win cost-first ranking despite having no total price; check for an actual non-null numeric value before declaring pricing ready.

Useful? React with 👍 / 👎.

Comment thread src/solution-metrics.js
Comment on lines +178 to +180
if (metrics.pricingStatus !== PRICING_STATUS.READY || metrics.estimatedTotalCost === null) {
throw new RangeError("pricing must be ready before estimatedTotalCost can enter decision ranking");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject underproduced metrics before decision ranking

When fileUnderproduction or pairUnderproduction is positive, createSolutionMetrics() correctly sets zeroUnderproduction to false, but this adapter still creates a rankable solution and drops all underproduction information. The ranker therefore cannot enforce its immutable zero-underproduction constraint, allowing an insufficient-production candidate to be recommended; reject these metrics before conversion.

AGENTS.md reference: AGENTS.md:L50-L52

Useful? React with 👍 / 👎.

Comment thread src/solution-metrics.js
pressPasses: metrics.pressPasses,
splitOrders: metrics.splitOrders,
impositionCount: metrics.impositionCount,
layoutCompactness: metrics.layoutCompactness,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Refuse unknown compactness before ranking

When a normalized solution explicitly uses the supported layoutCompactness: null state, this adapter passes the null through. The existing ranker converts objective values with Number(...), so null silently becomes 0; a compactness-first profile then treats missing data as a real worst score instead of rejecting an incomplete metric, potentially changing the recommendation.

Useful? React with 👍 / 👎.

Comment thread src/solution-metrics.js
orderedFinishedQuantity = null,
productionCost = null,
} = {}) {
const normalizedCost = normalizeProductionCost(productionCost);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Verify imported cost belongs to the same solution

When a caller accidentally supplies a productionCost calculated for another candidate, the normalizer accepts its total while independently retaining this solution's physicalSheets, colorPlates, and layoutForms. Because the cost object already records all three basis counts, compare them here before constructing the normalized model; otherwise ranking can use a cost that contradicts the candidate's production metrics.

Useful? React with 👍 / 👎.

@sunpole
sunpole merged commit ced3153 into main Jul 26, 2026
3 checks passed
sunpole added a commit that referenced this pull request Jul 26, 2026
Close Codex review findings from PR #14 by hardening normalized solution metrics before decision ranking: null cost stays incomplete, underproduction and unknown compactness are rejected, and imported production cost must match the candidate metrics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant