The risk-surface interview cannot be re-run, and its menu offers the same set twice #206
Labels
No labels
already-shipped
bug
documentation
duplicate
enhancement
external-review
good first issue
help wanted
in progress
invalid
needs-decision
proposal
question
security
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: crenshawdev/cadence-archived#206
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The one-time risk-surface interview is the only configuration question Cadence asks on its own, and it is the one a user has the least control over: it fires implicitly, once, and there is no way to reach it again.
1. No user-triggerable entry point
The interview lives in
cadence-core/references/review-triggers.md:430-465and fires only from inside arisk_surfacefire whose step-1route.mjs resolvereportssurfaces_answered: false. That is deliberate —/cad-new-projectand/cad-adoptboth forbid configuration questions in their own prose and success criteria (D-15) — but the consequence was not intended: once answered, the set can only be changed by hand-editingreview.triggers.risk_surface.surfacesin.planning/config.json, or by deleting the key so the next fire re-asks.grep -i surface skills/cad-config/SKILL.md cadence-core/workflows/config.mdreturns one hit, and it is the verb./cad-configcannot run the interview, cannot show what the scan currently evidences, and cannot re-run it after the repo's structure has changed — which is the normal case: a project that adds Stripe six months in has abillingsurface its answered set does not cover, and nothing ever revisits the question.Wanted: a
/cad-configarm that runsdetect-surfaces, shows the current answered set beside what the scan now evidences, and offers to re-answer. Re-running must be non-destructive of the existing answer unless the user picks a new one.2. The menu contains two identical options
lib/surface-scan.mjs'sscanTreereturnsrecommended = [...CATEGORIES]unconditionally. The comment above that line gives the reason and the reason is correct: absence is not provable from structure, and framework built-in auth (Djangocontrib.auth, Railshas_secure_password) ships no separate dependency, so a narrowed recommendation would persist a scope that skips the only blocking review the project has.review-triggers.md:451was written against the previous contract and still describesrecommendedas "what it evidenced, plus the categories no structure can ever evidence (unspeakable)". It then instructs the caller to fill the remaining option slots with "the evidenced categories alone, and all eight."Since
recommendedIS all eight, option 1 and that last option are the same list. Rendered against a demo repo (Express + Stripe + Prisma + Passport, withauth/,migrations/,api/,workers/, a.sqlfile and anopenapi.yaml), the scan evidenced six categories and the menu came out as:The fix is the prose, not the code. The two arms collapse into one:
recommendedis all eight either way, andinconclusivenow changes only the REASON the option states, never the set it offers.evidencedandunspeakablestay in the return and stay in the ask, because they are what that reason is built from.3. Presentation
The seam already binds this correctly —
references/seams.md:12-25specifies the structured-choice tool, at most four options, recommended first and labelled, never pre-selected. Worth an explicit check that the interview is actually rendered that way at the fire site rather than as prose, since the whole interview is executed by a model reading a reference file and nothing structural enforces the rendering.Acceptance
review-triggers.mdandlib/surface-scan.mjsagree on whatrecommendedcontains, with aprose-agreement.test.mjsarm that fails when they drift. The existing check atprose-agreement.test.mjs:180verifies the category LIST agrees across the schema enum, the route table and the detection list, and verifies nothing aboutrecommended— which is why this drifted silently.