Conversation
The existing one-liner was too soft to bind and had been ignored: 875 comment lines on dev, 39 of them citing a PR, issue, or ENGINEERING §. Replaces it with a hard 2-line cap, an explicit no-provenance rule, and a before/after example, then wires it into the pre-PR self-check so review-agent scores it. Capped at Low/Nit so comment wording can never deadlock the review-revise cycle. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…very comment citing an issue, PR, or ENGINEERING § is gone: git blame already links each line to its PR, and one of these refs pointed at a workflow file deleted three commits ago. Comment-only except the ENGINEERING.md clarification that the two-line cap counts prose, not JSDoc delimiters. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Restore load-bearing facts dropped by condensing: static-path precedence in the auth webhook route, and formatRelativeTime's bucket contract. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop the ENGINEERING §4 provenance citation from the stale-link guard comment in position-actions.ts, paraphrasing the reasoning instead — this PR's own §7 rule forbids doc-section citations in comments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rebases the branch onto the current origin/dev (release bumps + #412/#325/ #383/#358 landed since the last rebase). Reapplies the comment-discipline sweep at a stricter bar (one line by default, two only where a fact genuinely can't compress further, terse fragments over narrated sentences) across the files this cycle covered; ENGINEERING.md/review-agent.md were not editable from this agent role, so their prose still describes the prior ≤2-line bar. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The docs still described the superseded two-line bar, and the files the revision agent stopped short of were still written to it. Rewrites §7 and the review-agent dimension around one line by default, terse fragments rather than sentences, and sweeps the rest of the codebase to match. Also clears provenance the earlier passes missed: #356 in lib/auth/guards.ts and prisma/data/managers.ts, review-finding ids in the question dialogs, and issue refs across the seed fixtures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Condensed the 3-line isRedirecting comment that merged in from #368 (application-stepper.tsx) down to the established one-line bar. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…line #418 Tighten Comment Discipline Across Code And Docs
Derive read-only state from the shared NON_REVIEWABLE_APPLICATION_STATUSES constant instead of a hand-written check so the UI cannot drift from the action's own guard, add explanatory copy, and swap the hardcoded trigger id for useId() so multiple controls per page stop colliding. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Needed for the archived-positions disclosure on /positions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
getManagedPositions encoded "still worth attention" as a where OR with no draft branch, so a manager's drafts never appeared. Invert it: fetch every non-deleted managed position and decide active vs archived with a pure predicate, isPositionActive, so the list and (#360) the manager edit freeze share one source of truth instead of two implementations that can drift. Archived positions render behind a collapsed disclosure instead of being dropped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Swap the radix-ui umbrella dependency for the scoped @radix-ui/react-collapsible package, matching every other primitive wrapper in components/ui/ and dropping ~40 unnecessary sub-packages from the lockfile. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
status never auto-flips to 'closed' when closesAt elapses (confirmed: no cron/trigger does this, and PositionStatusBadge / getRecentlyClosedPositions already treat status:'open' + past closesAt as closed for display purposes). isPositionActive checked the raw status column only, so a manager-visible "Closed" position whose status was still 'open' in the DB stayed in the active My Positions list forever. It now delegates the closed check to getPositionAvailability (status:'closed' OR 'closed_by_date'), matching the rest of the codebase's definition of "closed". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
isPositionActive's _count.applications where clause used NON_TERMINAL_APPLICATION_STATUSES (includes 'draft'), but that branch is only reachable once a position is already closed, and submitApplication refuses a closed position, so a stray draft could never leave 'draft' and the position could never archive. Switched to UNRESOLVED_APPLICATION_STATUSES, matching getAdminPositions and the count shown on the position card. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes stale isPositionActive JSDoc and removes the now-dead NON_TERMINAL_APPLICATION_STATUSES constant left behind by 90e6e76. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…aft-positions #340 Managers Cannot See Draft Positions
the client's readiness check now reads snapshot ?? profile (same as the server), and submitApplication/reopenApplication backfill any missing snapshot rows from the profile inside a transaction before validating, so a question added after draft creation surfaces as an empty required field instead of an unexplained submit failure. Existing drafts also bypass the profile-completeness gate on the apply page, since that gate protects creating an application, not resuming one already in progress. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix client/server mismatch for deliberately-cleared global answers: initialGlobalValues and hasNewRequiredGlobals now branch on snapshot row presence, not value length, so a cleared (but existing) answer row no longer falls back to the profile value. Also memoize the per-render derived values (initialGlobalValues, initialPositionValues, hasGlobalRow, hasNewRequiredGlobals) since they only depend on props that don't change after mount. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Condense this PR's comments to the one-line-by-default bar from ENGINEERING.md §7 and drop the #398 provenance citation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e-after-global-question #355 Keep In-Progress Drafts Submittable After a Global Question Is Added
reads/writes to APPLICANT_EDITABLE_APPLICATION_STATUSES (draft, withdrawn) instead of ownership alone, closing the gap where a submitted application could be silently rewritten and resubmitted. The apply page renders a read-only "already applied" card for non-editable statuses, and the stepper/question components surface the action's exact refusal message via toast instead of a generic one. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Surface the specific refusal message on the "Use profile answers" revert path, mirroring the onSave/blur path's exact-sentence toast instead of the generic "Failed to revert some answers" copy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Applies the project-wide comment-discipline rule (ENGINEERING §7) that landed after most of this PR's comments were written: one line by default, no provenance refs, no narration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r-writes-and-submission #345 Gate Application Answer Writes and Submission on Application Status
Prefetches now skip the proxy matcher entirely, the public tier is sized for a page view plus its RSC payload (10 -> 60/min), and a rate-limited document navigation gets a real 429 page instead of raw JSON, while RSC/fetch callers keep the JSON 429. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Git's default core.commentChar of '#' makes every path that re-reads a message through the editor (rebase, --amend) strip the mandated '#XXX' subject as a comment, and the commit-msg hook does not run there. Pin it to ';' in prepare, teach the hook to skip ';' comments, and validate every commit in a PR by invoking the hook itself so the rules cannot drift. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`git merge -m` writes a message file with no trailing newline, and POSIX `read` returns non-zero on such a line, so the loop dropped it and found no subject at all. The hook then exited 1 before the "Merge " exemption could run, blocking the merge outright. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deleted one comment that only restated its variable's name and compressed the rest to one line; two genuinely non-obvious correctness constraints stay as rare two-line exceptions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Redo of a revise-agent cycle whose fixes were lost when its worktree was deleted before pushing. Collapses the 5/4/3-line comment blocks in scripts/check-hooks.mjs and commit-message-check.yml down to one line by default, keeping the two genuinely non-obvious traps (commentChar pinning, non-fatal config write) as compressed 2-line exceptions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces partitionAnswerValue/isAnswered (lib/utils.ts) so a stored
answer that no longer fits its question's current type/options is
split into the part still renderable ("fitted") and the rest
("orphaned"), instead of one silently overwriting the other on the
next blur. Both applicant editors (ApplicationQuestion, ProfileQuestion)
and the stepper's read-only card now render controls from `fitted` only,
surface `orphaned` via a new read-only AnswerMismatchNotice, and build
every write from `fitted` so a render-time mismatch can never become a
write. "Answered" is redefined via isAnswered everywhere required-answer
checks happen (submitApplication, getProfileCompleteness, the apply-page
gate) so client and server agree on what counts as answered.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consolidating QuestionShape into AnswerQuestion dropped FORMAT_INPUT_TYPES and the type= prop, so email/phone/url/zip answers always rendered a plain text input. Relocated the map to lib/constants.ts alongside the other format constants so ProfileQuestion can adopt it later. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drops the ENGINEERING §7 citation from the partitionAnswerValue JSDoc and condenses every other comment this PR introduced (issue refs, narration, multi-paragraph JSDoc) to the one/two-line terse-fragment bar, without losing the invariants they document. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Condenses multi-line/duplicated comments this PR introduced to one-line terse fragments and drops a couple that naming already carried, without losing the invariants they documented. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes a cross-function reference comment in application-stepper.tsx and condenses the last two-line comment in profile.ts, completing the ENGINEERING §7 comment-discipline pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-commit-subjects #430 Stop Rebases Stripping Commit Subjects and Validate Messages in CI
…s-on-question-shape-change #354 Preserve Stored Answers When A Question Type Or Options Change
…-throttles-browsing #404 Public Rate Limit Tier Throttles Normal Browsing And Returns Raw JSON
Adds a shared getAnswerValueError validator (lib/constants.ts) enforcing choice membership, single-vs-multi value counts, and per-value/array length caps. Both answer-writing actions call it as the real backstop; both applicant editors call it inline so the client shows the same message before round-tripping to the server. Option count/length are capped via the existing validateOptions refinement so an admin can't author a choice that's unselectable by the new answer-side limits. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Distinguish a re-thrown { error } from a genuine unexpected throw so
autosave catches never leak an authorization guard's raw message.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-against-question-options #352 Validate Answer Values Against Question Options And Add Length Limits
…-for-withdrawn-applications #366 Disable Status Control For Withdrawn Applications
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
bump version to v1.4.3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v1.4.3
Changes
Testing plan
/positionssigned out, reloading ~15 times in a minute → pages keep loading normally; no raw JSON error/profileinstead, return to the draft and submit without touching it → submits successfullygoogle.com(no scheme) → accepted; enter obvious non-URL text → inline error