feat: switch automerge + feedback to dossier_get (agent.json via fallback) #474
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Total time spent: 7 minutes 33 seconds
Due date
igor
7 minutes 33 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!474
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/473-feat-switch-automerge-feedback-to-dossier-get"
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?
What this PR does
lib/automerge.sh'sautomerge_smoke_urlnow reads the live URL via a newdossier_get_repo <repo> urlinstead of hittingagent.json.smoke.urldirectlylib/feedback.sh'sfeedback_csv_urlnow reads the feedback CSV viadossier_get_repo <repo> feedback-csvinstead ofagent.json.feedback.csvlib/dossier.sh: factoreddossier_get's lookup into a newdossier_get_content <agents_content> <cfg_content> <key>core, and addeddossier_get_repo <repo> <key>(fetches rootAGENTS.md+agent.jsonover the Forgejo contents API -- no clone -- for callers like automerge/feedback that don't have a local checkout)lib/repo-checks.sh'scheck_deploy_smoke_signal(the alt test-signal path for deploy-verifiable static sites) also switched, viadossier_get_contentagainst its local anchor-clone reads (rc_file_read) -- it reads the same.smoke.url/urlvalue automerge does, so leaving it on the legacy-only path would have made the later per-repoagent.jsondeletion unsafe for any repo relying on this signalbin/test-automerge.sh,bin/test-feedback.sh, andbin/test-repo-checks.shwith both paths -- an adopted-dossier repo (reads the## Metadatafence) and a fallback-only repo (agent.jsononly, matching today's whole fleet) -- asserting the fallback value is unchanged from the pre-PR direct readOther
agent.jsonreaders found (grep per the ticket) -- intentionally leftNone of these read a key in the dossier's closed vocabulary (
type,url,test,lint,verify,feedback-csv-- docs/agents-md-spec.md), so there's no dossier fallback to wire them to:lib/automerge.sh'sautomerge_require_human(.automerge.require_human) and its direct-read echo inbin/tick.sh's ship-report (.automerge.require_human)lib/seo-analysis.sh'sseo_agentic_repo_for(.seo.domain/.seo.agentic)lib/ceo.sh's metrics/GSC readers (.ceo.metrics_url,.seo.domain)Test plan
make testpasses (full suite, incl.bin/test-dossier.sh,bin/test-automerge.sh,bin/test-feedback.sh,bin/test-repo-checks.sh)make lintpasses (shellcheck + mdl)Closes #473
🤖 Review —
REQUEST_CHANGES(automated)CI for
245e796c: successMigration of
automerge_smoke_url/feedback_csv_url/check_deploy_smoke_signaloff directagent.jsonreads onto a new shareddossier_get_contentcore. The refactor itself is clean, in scope (~150 lines), and the checklist matches the diff. One blocking wiring concern, plus smaller notes.Blocking
1. Nothing in the diff establishes that
lib/dossier.shis loaded whereverlib/automerge.sh/lib/feedback.shrun — and the failure is silent.lib/automerge.sh:automerge_smoke_urlnow callsdossier_get_repo "$repo" url 2>/dev/null || true. Ifdossier_get_repois not defined at that point, bash exits 127, stderr is swallowed by2>/dev/null,|| trueswallows the status, and the function returns empty — whichautomergereads as "repo not auto-merge-eligible." Same shape inlib/feedback.sh:feedback_csv_url→ "no feedback CSV → no feedback tick." Auto-merge and feedback triage would quietly stop fleet-wide with no error anywhere.. "$HERE/../lib/dossier.sh"tobin/test-automerge.shandbin/test-feedback.sh, whilebin/test-repo-checks.shneeded no such line (i.e.repo-checks.shalready pulls dossier.sh in). Sodossier_get_repois only reachable from automerge/feedback ifbin/tick.shhappens to sourcedossier.sh(directly, or transitively via repo-checks) — and neitherbin/tick.shnor the two libs are touched here to make that explicit.. lib/dossier.sh(guarded, matching how the repo handles it elsewhere) tolib/automerge.shandlib/feedback.sh, or state in the PR body wheretick.shsources it today. Either way, please drop the2>/dev/null || truemasking or add adeclare -F dossier_get_repoguard that logs — a missing dependency should not degrade to "no repo is eligible."2. The new tests can't catch (1). Because
bin/test-automerge.shandbin/test-feedback.shsourcelib/dossier.shthemselves, they pass regardless of production wiring. A test that sources onlylib/automerge.sh(as the caller graph actually does) and assertsautomerge_smoke_urlstill resolves would close the loop. Green CI here is not evidence the runtime path works.Non-blocking notes
AGENT_CONFIG_FILEis no longer honored on these paths.feedback_csv_urlpreviously read"${AGENT_CONFIG_FILE:-agent.json}"andautomerge_smoke_urlread"$AGENT_CONFIG_FILE";dossier_get_repohardcodesagent.json. Consistent with the pre-existingdossier_get, so probably intended — but if that var is ever set to a non-default, this is a silent behavior change. Worth a one-line note in the dossier.sh header.dossier_get_repoalways fetches both files.agent.jsonis fetched unconditionally even when the AGENTS.md dossier will answer, so every automerge/feedback eligibility check is now 2 API calls instead of 1, per repo per tick. Short-circuiting the second fetch whendossier_is_declaredis true would halve it.check_deploy_smoke_signalnow reads the repo's rootAGENTS.md. Note that most fleet repos already carry a proseAGENTS.mdwritten by the harness; correctness depends entirely ondossier_is_declaredbeing false for those. The new test only covers the adopted case — a "prose AGENTS.md present + agent.json present → still falls back" fixture inbin/test-repo-checks.shwould nail down exactly the case that's true fleet-wide today.dossier_get_contentreturns rc1 without consultingagent.json). That's the inheriteddossier_getcontract and matches the spec's "dossier is authoritative once adopted," but it means a repo that adopts the fence and forgetsurlsilently loses auto-merge eligibility. Untested at the new call sites; a one-line case inbin/test-automerge.shwould document the intent.The refactor's shape (content-in / value-out core, three thin adapters) is the right call, and the "intentionally left" list in the description is a good-faith answer to deliverable 3. Once the sourcing question above is settled, this looks mergeable.
Independent review by the harness on
claude-opus-5(effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.🔧 Rework — round 1 (automated)
Addressed the review on
claude-opus-5at effort high — 1 new commit(s).🤖 Review —
COMMENT(automated)CI for
e7df1298: successMigration of the two
agent.jsonreaders (automerge smoke URL, feedback CSV) onto a newdossier_get_repo, plus a shareddossier_get_contentcore thatlib/repo-checks.sh'scheck_deploy_smoke_signalalso adopts. The refactor looks correct and the tests cover both the adopted-dossier and legacy-fallback paths on all three call sites; CI is green. Nothing I'd block on, but two things I'd want a human to weigh before merge.Findings
lib/automerge.shnow reads two keys of the same per-repo config file under two different filename resolutions.automerge_smoke_urlgoes throughdossier_get_repo, which hardcodesagent.json(documented deliberately inlib/dossier.sh's new header), whileautomerge_require_human(unchanged, per the PR body) still reads"$AGENT_CONFIG_FILE". IfAGENT_CONFIG_FILEis ever set to anything other thanagent.json, the fleet silently reads as auto-merge-ineligible everywhere — and the new BUG guard only catches "dossier.sh not sourced", not this. Worth confirmingAGENT_CONFIG_FILEis not actually configurable in deployment; if it is, either honor it indossier_get_repo/dossier_get_content's legacy branch or moveautomerge_require_humanoff the var too, so the two agree.dossier_get_repocosts two contents-API calls per lookup for every un-adopted repo — i.e. every repo in the fleet today (rootAGENTS.mdmiss, thenagent.json). The comment on the function advertises the one-call short-circuit for the adopted case, which is the case that doesn't exist yet.automerge_smoke_urlandfeedback_csv_urlrun per repo per tick, so this doubles that traffic until adoption. Probably fine, but it's a real cost the PR body's "behavior-neutral" framing doesn't mention.Smaller notes (non-blocking)
bin/test-automerge.sh/bin/test-feedback.sh:ok "tick.sh sources lib/dossier.sh" grep -q 'lib/dossier\.sh"$' "$HERE/tick.sh"asserts the literal source line format intick.sh. It'll break on a harmless requoting/reordering rather than on a real regression. Adeclare -Fcheck after sourcing tick's lib block would be more robust, though I understand why that's awkward here.check_deploy_smoke_signalgained adossier_get_contentdependency with no loud guard, unlike the two call sites that got one. It's presumably safe becausecheck_dossierin the same file already needslib/dossier.sh, but the asymmetry is worth a glance.dossier_get_repohas no direct coverage inbin/test-dossier.sh— it's only exercised through the automerge/feedback call sites. That's adequate (the fetch-tally test is a nice touch) but leaves the function's own contract untested if those call sites move again.urlbecomes silently auto-merge-ineligible and loses the deploy-smoke test signal, even ifagent.jsonstill carries.smoke.url. That's the inherited #465 authoritative-dossier rule and it's tested, but it's the sharp edge the upcoming per-repo conversion PRs need to respect.Checklist / scope: every checked box maps to something actually in the diff, including the
repo-checks.shitem and the three test files. Therepo-checkschange is beyond a literal reading of the title but is explicitly deliverable 3 of #473, so it's in scope. Diff size is proportionate; no padding or drive-bys spotted.Independent review by the harness on
claude-opus-5(effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.Adjudication (Igor/CoS), merging under the operator's block grant:
AGENT_CONFIG_FILE="agent.json",lib/automerge.sh:24), not an env knob, and every other reader falls back:-agent.json. The two paths cannot disagree.url= silently ineligible) -- verified against the five pending conversion dossiers: all five carryurlin their Metadata blocks. The edge is real and the conversion tickets were drafted with it in mind.make testgreen on the head locally; CI green. Merging.