Add two-axis ratchet for agent-config PUT; document open content-axis ruling (#7470) - #7970
Add two-axis ratchet for agent-config PUT; document open content-axis ruling (#7470)#7970bolichen97 wants to merge 3 commits into
Conversation
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
Design Review (Fable 5) — 🟡 CONCERNSDesign-level review of Design-Verdict: CONCERNS Sound ratchet test, but the "ruling brief" invents an unindexed top-level Watch
Suggestions
[DESIGN-REVIEWED] 0161a3c |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Closing — already landed on
|
Addresses #7470 (agent-config PUT: a stale snapshot can revert a live app bridge to a superseded definition).
The issue has two clearly separable halves, with different readiness levels — the maintainer comment calls this out explicitly. This PR lands the half that needs no ruling and surfaces the half that does.
What landed (ruling-free)
Region-level two-axis existence ratchet. The issue's "A gate, either way" section asks for a test asserting that every key of an app-owned
mcpServersregion (keys containing:, excluding host-owned names) has its existence decided by on-disk state on both the present-drop axis (#7089) and the absent-preserve axis (#6975), so adding a new owned region without a present-axis rule fails the suite instead of shipping. That test genuinely did not exist. It now does:test_app_owned_region_existence_is_decided_on_disk_on_both_axes._putharness (no mocking of the drop / merge / ownership decision).What is documented, not implemented (needs a maintainer ruling)
The content axis — where an
<app>:<server>name is on disk and in the submission, the submitted row still wins, so a stale editor snapshot can revert a bridge the platform already corrected (e.g. abackend.port: "auto"app rewritten to its live port by_resolve_live_mcp_url) — reverses the editor-snapshot-wins contract kept deliberately in #5899 and re-affirmed for #6664. Per the issue and the maintainer comment, whether it may be reversed at all, and if so which candidate shape (on-disk row substitution vs. optimistic-concurrency/etag) closes it, needs a maintainer ruling. #7089 shipped only the deletion half for exactly this reason.No behavioral source change was made. The handler docstring, the spec decision table, and
test_app_owned_entry_present_in_the_snapshot_is_updatedalready correctly reflect the open ruling. A decision brief assembling everything the decider needs (both candidate shapes with costs, the "breaks EVERY kiro session" blast radius, the self-heal mitigation, and verified current file:line anchors) is added at.agents/tasks/task-agent-config-content-axis-ratchet/CONTENT-AXIS-RULING.md.Testing
pytest -q test/test_agent_config_merge_on_write.py→ 47 passed (baseline 46, +1 new).test_agent_config_merge_on_write.py,test_api_agent_config_put_succeeds.py,test_agent_config_owner_gate_invariant.py→ 67 passed.del submitted[name]drop in_drop_unbacked_app_entriesmakes the new test FAIL on its present-axis assertion; restoring returns to green withgit diff src/empty.git diff src/is empty — the committed diff is exactly two files (the new test and the decision brief).