Repository navigation
fix(data): every project-data question through the question tool; skills name the repository - #672
mlieberman85 wants to merge 10 commits into
Conversation
18bd63e to
d8eabe8
Compare
d8eabe8 to
69516e9
Compare
Marc-cn
left a comment
There was a problem hiding this comment.
Reviewed its own three commits. Every question gets a selector, long choice lists show four and point to Other, free text offers Skip / Answer in chat, and the skills name the repository on every call (the #646 fix). Two things to check, not blockers: (1) for a choice with more than 4 values the code adds 'Choose Other to type a value not listed below' but does not name values 5+ in the question; fine if prompt already lists them, otherwise they are visible only in allowed_values. (2) the free-text value_map maps Skip and Answer-in-chat to the strings "SKIP" and "ASK_USER_FOR_VALUE"; an agent applying answer_mapping mechanically could pass "SKIP" as the answer. null, or leaving those labels out of value_map, would be safer. Good to merge in order.
69516e9 to
41a59e1
Compare
Marc-cn
left a comment
There was a problem hiding this comment.
Re-read the head of fix/question-picker, own commits only. Routing every question through the question tool is the right fix for #655, and the enum vocabulary check keeps "type it under Other" safe for choice keys. One hole it opens, and two doc/skill inconsistencies:
- The two labels added to every free-text key, "Skip for now" and "Answer in chat" (tools.py:1058-1062), and the value_map sentinels "SKIP" / "ASK_USER_FOR_VALUE" (tools.py:872), are accepted by the server as confirmed values: context_writes.py:189-193 refuses only None and out-of-vocabulary enum values, and free-text keys have no vocabulary. If the agent forwards the chosen label — which is what AskUserQuestion returns — confirm_project_data(security_contact="Skip for now", ...) is recorded as a person-confirmed value (maintainers becomes ["Skip for now"]). Procedure prose is the only guard, on a server whose premise is that the agent is untrusted. Please refuse those four strings (and inside list values) in record_value_confirmation with a clear reason, define them once in darnit.server.procedures so core and baseline share them, and add a test. (Follows up the value_map note in my first review.)
- specs/042-candidate-integrity/contracts/context-confirmation-tools.md:27 still says selector options are omitted above 4; framework-design 1748 (changed here) says the opposite and names that contract as the definition. The sentinels and the free-text selector should be documented there too.
- darnit-comply/SKILL.md:42 now says to call the audit again after confirming data; line 85 still says "Do NOT run a separate audit before calling remediate_audit_findings". Reword 85.
Not blocking: "name the repository on every call" is enforced only by skill text plus a test that inspects two lines (darnit-remediate:110 already names none); a warnings entry from get_pending_data / the audit when target is None would make #655 a real fix. The agent-flow test takes answers from the ANSWERS dict, not from ask_user_batch / answer_mapping, so it can't fail on point 1.
get_pending_data and get_judgment_requests carry a 'procedure': the ordered steps for the result, with calls that name only the repository the caller named. A confirm_project_data result on a server with get_pending_data ends with the next get_pending_data call. The text has one home in the framework, so skills and clients defer to it. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
darnit-comply told the agent to "follow the /darnit-data skill" and "follow the /darnit-audit skill", but nothing loads another skill's text, so the comply run improvised data collection from one line and asked questions differently from a darnit-data run. darnit.server.procedures holds the steps once. get_pending_data returns them as 'procedure' (show candidates labelled unconfirmed, ask every question, per-question skip, one confirm_project_data call with accept_candidates filled only after a yes, the next call, the review of stored values, the summary), get_judgment_requests returns the judging steps on every page, and the baseline confirm_project_data result ends with the next get_pending_data call. Calls name only the owner and repo the caller passed, never ones read from the checkout's remote, and hold no candidate value. The skills defer to the procedures instead of restating them, and no skill tells the agent to follow another one (a test checks). The comply and remediate skills pass owner and repo to remediate_audit_findings, which needs them to find operator-side confirmations (darnitdevorg#612). Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
A page now names, in 'skipped', the controls left out because they already have a stored PASS candidate, and the judging procedure says not to request them again. In the darnitdevorg#644 e2e runs the agent called the tool again with those ids and got empty pages back. Refs darnitdevorg#644. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
…l_ids Section 7.10 and the 042 contract: get_pending_data takes no host, so the confirm_project_data call in its procedure names host as a placeholder to fill for a repository not on github.com. Answers are mapped by answer_mapping, where a No on a candidate, or Other, is the value the person typed. The next get_pending_data call keeps the caller's control_ids. The contract now lists procedure. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
Review of darnitdevorg#671. The procedure that replaced the old directive lost two of its instructions: - Step 4 built the confirm_project_data call without host, so on a repository not hosted on github.com an agent following it verbatim recorded confirmations under github.com. get_pending_data takes no host, so step 4 now names it as a placeholder. - Step 4 said only that Yes/No questions take true/false. A candidate question is also Yes/No, so a No could be sent as false. Step 4 now maps answers by answer_mapping: a No on a candidate, or Other, is the value the person typed. Step 5 and the next step after confirm_project_data keep the caller's control_ids, so a scoped collection stays scoped. The ASCII test checked json.dumps output, which is always ASCII; it now checks the text itself. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
Since darnitdevorg#552, _build_ask_user_params returned no selector for free-text questions or for choice questions with more than 4 values, so a batch was split between Claude Code's question tool and plain text. Every question now has a selector: a long choice list shows its first 4 values and names all of them in the question (each typeable under Other, FR-015), and a free-text question offers "Skip for now" and "Answer in chat", never a value. Word-boundary headers and the yes/no hint in the question came from darnitdevorg#657 and are kept as merged. The spec (7.x) and the data procedure say the same. Refs darnitdevorg#650, darnitdevorg#655. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
The audit and comply skills called the audit without owner and repo, so confirmed project data and stored PASS candidates, which apply only to a named repository, were never applied: after answering the data questions a re-audit showed the same results, and submit_judgment (which requires the name) saw a different set of PENDING controls than the audit. Every skill now asks the person to confirm the repository, suggesting the origin remote, and names it on every call; comply re-runs the audit after data is confirmed. A test checks every skill. Refs darnitdevorg#646, darnitdevorg#655. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
Refs darnitdevorg#655. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
Section 7.10 and the 042 contract: confirm_project_data refuses "Skip for now", "Answer in chat", "SKIP" and "ASK_USER_FOR_VALUE" as a value, alone or inside a list, since an agent may forward the label its question tool returned. The contract no longer says a selector is omitted above 4 values: every question has one, a long choice list offers its first 4 and names them all, and a free-text question offers the two labels above, never a value. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
Review of darnitdevorg#672. Every free-text question now offers "Skip for now" and "Answer in chat", and answer_mapping maps them to "SKIP" and "ASK_USER_FOR_VALUE". record_value_confirmation refused only None and out-of-vocabulary enum values, so an agent that forwarded the label AskUserQuestion returned recorded it as a person-confirmed value, for example maintainers = ["Skip for now"]. Only the procedure text guarded against that. record_value_confirmation now refuses those four strings, alone or in a list, before and after coercion, with a reason that says to leave the key out or ask for the value. They are defined once, in darnit.server.procedures, and the selector, answer_mapping and the procedure use them. The agent-flow test forwards a "Skip for now" label and requires the refusal. darnit-comply said both to re-run the audit after confirming data and "Do NOT run a separate audit"; the gotcha now says only not to audit just to feed remediate_audit_findings. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Michael Lieberman <mlieberman85@gmail.com>
41a59e1 to
c77cb47
Compare
|
Thanks, good catch on point 1. All three points are fixed in two new commits on top: "docs(spec): a selector label or answer_mapping marker is not an answer" and "fix(data): refuse a selector label or marker as a confirmed value". Rebasing on the updated #671 conflicted in
Not done, from your non-blocking notes: a warning from The headless comply run on #693's head, which includes this branch, is in my reply on #693. Drafted with AI assistance (Claude), reviewed and filed by me. Measurements quoted were executed and verified. |
Marc-cn
left a comment
There was a problem hiding this comment.
Approved on c77cb47. The server now refuses 'Skip for now', 'Answer in chat', 'SKIP' and 'ASK_USER_FOR_VALUE' as a confirmed value, alone or in a list, before and after coercion and on the operator path, with the strings defined once in darnit.server.procedures and used by the selector, answer_mapping and the procedure; the agent-flow test forwards the label over MCP and requires refused. The 042 contract documents the free-text selector and the markers, and darnit-comply line 85 now says what the one extra audit is for. On the VM against main: tests/darnit/server + darnit_baseline + config + the MCP integration suite 1983 passed, ruff and validate_sync clean.
Summary
Questions. Since #552,
_build_ask_user_paramsreturned no selector for free-text questions or for choice questions with more than 4 values. So one batch was split between Claude Code's question tool and plain text. Every question now has a selector:This builds on #657, which already merged the word-boundary headers and the yes/no hint in the question.
Repository naming. The audit and comply skills called the audit without owner and repo. Confirmed project data and stored PASS candidates apply only to a named repository, so they were never applied: after answering the data questions, a re-audit showed the same results (#646). Every skill now:
Comply re-runs the audit after the data is confirmed. A test checks every skill.
Spec: 7.x and the data procedure. The flow test now checks that every question is in
ask_user_batch, with at most 4 per round.Refs #650, #646, #655.
Type of Change
Framework Changes Checklist
docs/architecture/framework-design.md, 7.x)uv run python scripts/validate_sync.py --verboseand it passesTesting
uv run pytest tests/on the whole rebased stack (18bd63e): 5286 passed, 18 skippeduv run ruff check .End-to-end
darnit-e2e: headless/darnit:darnit-audit openssf-baselinethrough Claude Code. Confirm tools are disallowed and the repository is named in the prompt.get_judgment_requestswas larger than Claude Code's tool-result limit and was saved to a file. The agent's attempt to read it with Bash was denied. This is the oversized single-request follow-up.AI assistance
Claude Code (Claude Opus) wrote the change, tests and this description; I reviewed them and ran the e2e.
Drafted with AI assistance (Claude), reviewed and filed by me. Measurements quoted were executed and verified.