Skip to content

Harden the build-verify gate and fix the revise-rating spec contradiction - #7

Merged
chumleesockson merged 1 commit into
mainfrom
harden-verify-gate-and-revise-spec
Jun 27, 2026
Merged

Harden the build-verify gate and fix the revise-rating spec contradiction#7
chumleesockson merged 1 commit into
mainfrom
harden-verify-gate-and-revise-spec

Conversation

@chumleesockson

Copy link
Copy Markdown
Owner

Why

A run-through of the Code App demo surfaced a cluster of failures that only appeared at the deploy build, not at the per-task gate: wrong response shape (.value vs .data), string-where-Choice-integer track values, a create payload missing statecode, test globals leaking into the production build, a runtime type is invalid ... got: undefined, and revising a rating creating a second Dataverse row.

Almost all of these trace to one thing: the gate didn't run the compiler. AGENTS.md and tasks.md both claim npm run verify "chains typecheck + lint + test", but the scaffold skill only told the agent to "add a verify script", so the fast model wrote lint && test and dropped tsc. That is a configuration failure, not a model failure (Day 1 / Day 5), which is exactly what this harness exists to prevent. The fixes go into the factory (the scaffold skill and AGENTS.md) and the spec (the asset), never into the throwaway src/.

What changed (harness only, no app code)

Gate now compiles

  • scaffold-code-app skill (both .agents and .claude copies): step 4 is now prescriptive, with the exact package.json scripts. verify = npm run typecheck && npm run lint && npm run test -- --run, typecheck = tsc -b.
  • AGENTS.md: the gate bullet now states the typecheck is non-optional and names the failure mode it catches.

Test types stop polluting the app build

  • Exclude *.test.* and setupTests.ts from tsconfig.app.json; move vitest/globals into a referenced tsconfig.test.json so tsc -b still typechecks the tests. Removes the need to bolt vitest/globals onto the app config.

Mocks can no longer drift from the real contract

  • AGENTS.md Stack notes: fixtures must be typed from the generated model (so .value-vs-.data, string-vs-integer, and a missing statecode become tsc errors, not green-but-wrong mocks), plus one un-mocked smoke render of App through the real module graph (catches the default-vs-named import / import-resolution runtime crash the mocked suite hid).
  • task-1 and task-3 gates reference these rules.

The revise-a-rating bug was a spec contradiction, so it's fixed in the spec

  • The spec specified an Edit affordance but only ever named create for persistence, so a revise duplicated the row. dataverse-schema.md now defines an update_feedback contract (Eppc_feedbacksService.update on the id create returns), §4 says one row per rating not per submission, §9 adds a BDD scenario asserting revise updates and does not create. session-feedback-instantiation.md §4 and task-3 updated to match. The anonymity boundary (no cross-device dedupe) is stated explicitly.

Minor

  • ESLint ecmaVersion pinned to 2022 to match the app's target (was the starter's 2020).

Whitepaper alignment

  • Day 1 (New SDLC) / Day 5 (Spec-Driven): "most agent failures are configuration failures." Every fix hardens the harness config rather than patching generated code.
  • Day 5: code is disposable, the spec is the asset. The revise bug is fixed in the spec and its BDD acceptance scenario, not in App.tsx.
  • Day 4 (Agent Quality): the typecheck gate, typed fixtures, and the un-mocked smoke render strengthen the verification layer; the create-payload re-check extends the "agents auditing agents" pass to the write task.

No src/, package.json, or tsconfig* files are committed: those are generated fresh by the scaffold skill on the day, so the fix lives in the skill's instructions, which now produce the correct config by construction.

…tion

Most demo failures only surfaced at the deploy build because the gate did
not run the compiler: the scaffold skill said "add a verify script" and the
fast model wrote lint+test, dropping tsc. Make the factory produce the right
config by construction, and fix the spec defect behind duplicate feedback rows.

- scaffold-code-app (.agents + .claude): prescribe exact package.json scripts
  so verify = typecheck (tsc -b) + lint + test; split test types into
  tsconfig.test.json so they stop polluting the app build; pin eslint to es2022
- AGENTS.md: gate must compile; fixtures typed from the generated model; one
  un-mocked smoke render through the real module graph
- dataverse-schema.md: add update_feedback contract + statecode note; §4 one
  row per rating not per submission; §9 BDD scenario for revise-updates-not-creates
- instantiation §4 and task-1/task-3 gates updated to match

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 27, 2026 11:53
@chumleesockson
chumleesockson merged commit 3bb5480 into main Jun 27, 2026
1 check passed
@chumleesockson
chumleesockson deleted the harden-verify-gate-and-revise-spec branch June 27, 2026 11:54

Copilot AI 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.

Pull request overview

Hardens the repository “harness” so the per-task npm run verify gate actually catches TypeScript contract drift (and build-only failures), and resolves the spec contradiction that caused “revise rating” to create a second Dataverse Feedback row instead of updating the existing one.

Changes:

  • Updates Task 1 + Task 3 specs to require typed fixtures, correct service response shape usage, an un-mocked App smoke render, and revise-via-update behavior.
  • Updates the Dataverse schema spec to define an explicit update_feedback contract and adds a BDD scenario for revise semantics.
  • Makes the scaffold skill + AGENTS.md prescriptive about verify including tsc -b and about splitting app vs test TS configs to avoid test globals leaking into production builds.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
specs/tasks/task-3-rate-modal.md Expands Task 3 acceptance criteria to include revise-via-update and stronger test/gate requirements.
specs/tasks/task-1-data-layer.md Tightens Task 1 testing guidance to use typed fixtures and the real service response shape.
specs/session-feedback-instantiation.md Aligns instantiation behavior text with revise-via-update persistence semantics.
specs/dataverse-schema.md Defines update_feedback and adds revise-related BDD coverage and guidance.
AGENTS.md Makes the verify gate explicitly compile-first and documents typed fixtures + smoke render rules.
.claude/skills/scaffold-code-app/SKILL.md Makes scaffold instructions prescriptive for scripts/tsconfigs so the gate compiles and tests don’t pollute app build.
.agents/skills/scaffold-code-app/SKILL.md Same scaffold hardening as the .claude copy for agent parity.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +33 to +35
- **Revise updates, it does not create:** the card's Edit affordance reopens the modal and a second
submit calls `Eppc_feedbacksService.update` on the `eppc_feedbackid` the create returned (schema §8),
never a second `create`. One row per session, not one per submission.
Comment thread specs/dataverse-schema.md
Comment on lines +315 to +320
update_feedback: # Rate modal submit when revising an existing rating (the Edit affordance)
service: Eppc_feedbacksService.update
id: <eppc_feedbackid returned by the create call, held in app state>
changedFields:
eppc_rating: 3 # the revised integer 1..5
eppc_comments: "Sharper on reflection" # omit/empty when optional and blank
Comment thread specs/dataverse-schema.md
Comment on lines +379 to +386
Scenario: Revising a rating updates the existing row, not creates a new one
Given a session rated 4 in this app session, whose feedback id is held in state
And the Rate modal is reopened via the card's Edit affordance
When the attendee changes the rating to 3 and submits
Then Eppc_feedbacksService.update is called with that feedback id
And Eppc_feedbacksService.create is not called again
And the session still has exactly one feedback row
And the rated count does not change
Comment on lines +81 to +83
**b. Linter.** Add **ESLint + typescript-eslint + eslint-plugin-react-hooks** (plus the Vite
`react-refresh` plugin the starter expects), wired to `npm run lint`. Set the ESLint
`languageOptions.ecmaVersion` to **2022** to match the app's `target`, not the starter's `2020`.
Comment on lines +81 to +83
**b. Linter.** Add **ESLint + typescript-eslint + eslint-plugin-react-hooks** (plus the Vite
`react-refresh` plugin the starter expects), wired to `npm run lint`. Set the ESLint
`languageOptions.ecmaVersion` to **2022** to match the app's `target`, not the starter's `2020`.
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.

2 participants