Skip to content

feat: Phase 1 foundation — tests, CI, content accuracy, security - #2

Closed
Steel-tech wants to merge 7 commits into
fix/ai-model-retiredfrom
feat/foundation-hardening
Closed

feat: Phase 1 foundation — tests, CI, content accuracy, security#2
Steel-tech wants to merge 7 commits into
fix/ai-model-retiredfrom
feat/foundation-hardening

Conversation

@Steel-tech

Copy link
Copy Markdown
Owner

Phase 1 (Foundation) of the IronForge maximization roadmap (docs/plans/2026-06-17-001-feat-maximize-ironforge-plan.md). Stacked on the U1 model-fix PR (#1) — base auto-retargets to main once #1 merges.

Units

  • U2 — Test infra + CI gate. First tests in the repo: Vitest (+ Testing Library/jsdom) for unit/component, Playwright for e2e, and .github/workflows/ci.yml gating lint + typecheck + test. ESLint was a no-op; now uses eslint-config-next native flat core-web-vitals (21 pre-existing react-hooks violations downgraded to warnings, flagged for burndown).
  • U3 — Estimator hardening. Rule-of-thumb figures extracted to lib/estimator/constants.ts; inputs clamped at the calc boundary (and capped at 1e9 so absurd values can't overflow the bid); bonding markup derived from the profit/contingency constants.
  • U5 — Content accuracy. StateVerification metadata on StateData (WA/OR backfilled); persistent "not legal advice — verify with your state agency" disclaimer on every wizard step, with a last-verified date for verified states and a "not independently verified" notice for the 48 machine-generated ones.
  • U4 — Silent fallback fixed. getPhaseContent no longer serves Washington's content for an unknown state — it returns a labeled "data unavailable" phase. Contract test covers all 50 states × 7 phases.
  • U6 — API security. CSRF/origin gate extended from /api/chat to all API routes; security headers (CSP/HSTS/…) centralized in next.config.ts.

Verification

  • 49 tests across 8 files, all green · tsc --noEmit clean · lint clean · production build succeeds.
  • Code review: 5 reviewers (correctness, security, adversarial, maintainability, testing). No P0/P1. The security change was validated sound (CSRF gate closes a real pre-existing gap on bid-review/onboarding). Applied the high-value findings: estimator overflow cap + the test-coverage gaps (cost-line flags, non-union burden, cost-per-sqft, wizard navigation, unavailable/static phases).

Deferred / surfaced (not in this PR)

  • Durable (cross-instance) rate limiter + x-real-ip-first IP keying → plan U10 (Growth).
  • CSP 'unsafe-inline' on script-src (Next App Router constraint) → future nonce-based CSP.
  • Origin/Host divergence behind a rewriting proxy → env-driven origin allowlist if the deploy topology ever needs it (dormant on Vercel).
  • Pre-existing estimator dead fields (floors, craneType) and the 21 react-hooks lint warnings → depth/polish pass (U11/U12).

🤖 Generated with Claude Code

Steel-tech and others added 6 commits June 17, 2026 13:42
Set up the project's first test infrastructure: Vitest (jsdom + Testing
Library) for unit/component tests, Playwright for E2E, and a GitHub
Actions workflow gating PRs on lint + typecheck + test.

Replace the no-op ESLint config with eslint-config-next's native flat
core-web-vitals rules (no FlatCompat). Pre-existing react-hooks
violations are downgraded to warnings so the gate is green from day one,
to be burned down in the depth/polish pass. Seed one passing test per
layer (unit, component, e2e); e2e runs locally and is not in the CI gate.

Implements U2 of docs/plans/2026-06-17-001-feat-maximize-ironforge-plan.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tests

Move the inline rule-of-thumb figures (burden %, $/ton, profit, bonding,
etc.) into lib/estimator/constants.ts; clamp negative/NaN numeric inputs
at the calculation boundary so a bypassed HTML min hint can't poison a
bid; derive the bonding markup from PROFIT_PCT/CONTINGENCY_PCT so it
can't drift from the profit/contingency constants. Add 13 tests: golden
total, per-ton + compounding-order locks, monopolistic-WC and
prevailing-wage behavior, and clamping edge cases.

Implements U3 of docs/plans/2026-06-17-001-feat-maximize-ironforge-plan.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make data provenance a first-class field: StateVerification
(lastVerified / sourceUrl / effectiveDate) on StateData, backfilled for
the hand-crafted WA and OR states. getStateVerification() resolves a
well-formed view for every state — verified states carry their date,
machine-generated states report unverified rather than a misleading one.

A persistent, non-dismissable LegalDisclaimer renders on every wizard
step: "not legal advice — verify with your state agency", plus the
last-verified date for verified states or a "not independently verified"
notice for the machine-generated ones.

Implements U5 of docs/plans/2026-06-17-001-feat-maximize-ironforge-plan.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
getPhaseContent fell back to Washington's content for any state missing
from the registry — silently presenting one state's regulatory facts as
another's. Replace all six fallbacks with an explicit, labeled
"data unavailable for <state>" phase that points the user at their own
agency. Add a contract test asserting all 50 states x 7 phases resolve to
valid non-empty steps, that a non-WA state gets generated (not
Washington) content, that an unknown code gets the labeled phase (never
Washington), and that the chat-route step lookup finds a phase's steps.

Implements U4 of docs/plans/2026-06-17-001-feat-maximize-ironforge-plan.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The proxy enforced same-origin only on /api/chat. Generalize it to every
state-changing API request (non-GET/HEAD on /api/*), so /api/bid-review
and /api/onboarding are no longer open to cross-site calls. Move the full
security-header set (CSP, HSTS, frame/permissions policy) into
next.config.ts as the single source of truth — it covers static assets
the middleware matcher excludes — and drop the duplicate weaker set.
Narrow the proxy matcher to /api/*. Rate limiting stays in the route
handlers (in-memory, per-instance; a durable limiter is plan U10).

Implements U6 of docs/plans/2026-06-17-001-feat-maximize-ironforge-plan.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
From the foundation code review (no P0/P1; these are the high-value P2/P3s):
- Clamp estimator inputs to MAX_FIELD_VALUE (1e9) so an absurd or tampered
  value (e.g. 1e307) can't overflow the bid to Infinity/NaN — the clamp's
  stated invariant was false for large finite values.
- Add the flagged missing tests: overflow finiteness; estimator cost-line
  flags in the "on" direction, non-union burden, and cost-per-sqft; wizard
  navigation (getNextStep/getPrevStep across phase boundaries); and the
  unavailable / legal-federal / unknown-phase content paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 085f85c7-b0e1-4bfe-964d-e1b1504ef886

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/foundation-hardening

Comment @coderabbitai help to get the list of available commands and usage tips.

@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: 90f38da1e2

ℹ️ 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 .github/workflows/ci.yml
with:
node-version: 22
cache: npm
- run: npm ci

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 Regenerate the lockfile before running npm ci

In the new CI workflow, this step fails on a clean checkout: npm ci is npm's clean-install command, and running it in this repo exits with EUSAGE because package-lock.json is not in sync (Missing: @swc/helpers@ from lock file, caused by the new @vitejs/plugin-react-swc/@swc/core peer). As written, every PR/push hits this line and stops before lint/typecheck/tests; please regenerate and commit the lockfile so npm ci can install.

Useful? React with 👍 / 👎.

CI's node 22 npm rejected the lockfile (Missing @swc/helpers@0.5.23) while
node 24 (local dev + lockfile generator) accepts it via `npm ci`. Align
CI to node 24 so the clean install matches the committed lockfile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Steel-tech
Steel-tech deleted the branch fix/ai-model-retired June 18, 2026 06:18
@Steel-tech Steel-tech closed this Jun 18, 2026
@Steel-tech
Steel-tech deleted the feat/foundation-hardening branch June 18, 2026 06:26
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