feat: adapter-first enumeration + consistent issue filing - #43
Merged
Merged
Conversation
Fixes a silent failure mode where GitHub issues filed in a tracked milestone were invisible to amos because they had no corresponding local plan file. Milestone counts, `amos next`, `amos blocked`, and `amos graph` now enumerate from the adapter's source of truth and merge local plan files as optional overlays. - Adds `list_milestones`, `list_nodes_in_milestone`, `add_relationship` to the `Adapter` trait (default empty impls — non-GitHub adapters forward-compat). - `GhAdapter` implements all three via GraphQL. Reads GitHub's native typed relationships (`blockedBy`, `blocking`, `parent`, `subIssues`) so the DAG gets authoritative edges, not stale plan-file copies. - `GhAdapter::with_detected_repo` — detects `owner/name` from the scan root's git remote, so a default repo is available for milestone enumeration without requiring every reference to be fully-qualified. - New `amos sync-edges [--dry-run]` subcommand — one-time migration that pushes every local `blocked_by` / `blocks` frontmatter edge up to GitHub as a native `addBlockedBy` relationship. Idempotent; safe to re-run. Canonicalizes mirror declarations (A.blocks:[B] + B.blocked_by:[A]) before pushing. - `main.rs` merges adapter-sourced nodes with parsed local nodes. Local nodes win for AI-facing fields (body, context, labels); the adapter fills in state + native edges and contributes virtual nodes for issues without a plan file. - Skills: updates `amos` SKILL.md to reflect the new "GitHub is the source of truth, plan files are optional AI-notes overlays" model. Documents `sync-edges`. Other skills are unchanged — they were already adapter-correct. - 10 new unit tests for the pure helpers (remote URL parsing, JSON-to- AdapterNode mapping, trait-default fallbacks, registry routing). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Second half of the adapter-first push. The bug fix (PR title) stands on its own; this commit adds the authoring side — consistent issue filing and PR close-link coverage — so the workflow loop is symmetric: `amos-file` creates issues, `amos sync-edges` migrates old projects, `amos-next` consumes them and auto-closes every addressed issue on PR merge. - New `Adapter::create_issue(spec) -> CreatedIssue` trait method (default errors). `GhAdapter` implements via `gh issue create`, returning the canonical amos name + URL. - New `amos issue-create --scheme github --spec <path|->` subcommand. Reads an `IssueSpec` JSON from stdin or a file (title, body, milestone, labels, blocked_by, blocks, sub_issue_of), creates the issue, then applies every native relationship in one atomic pass. Partial relationship failures are reported in the result but don't roll back the creation — the issue exists, the skill can retry the edges. - New `amos-file` skill. Handles the authoring flow: capture intent, discover a project template (`docs/issue-template.md` or `.github/ISSUE_TEMPLATE/*.md`, falling back to an amos default), draft title + body, infer milestone + labels with AskUserQuestion as the fallback when confidence is low, extract explicit relationships from the user's intent, present the whole draft at an AskUserQuestion gate, and hand off to the binary via JSON spec. Supersedes the older plan-file-scaffolding `amos-create` skill. - `amos-next` Step 7 now collects every issue the branch addresses — not just the primary — by grepping the branch's commits for `Closes/Fixes/Resolves #N` and optionally parsing the branch name, so GitHub auto-closes all of them on merge. - Early-route `IssueCreate` before the local scan so projects with legacy plan-file frontmatter can still file new issues without having to run `amos migrate` first. - One new test covering empty-title rejection. Existing test count unchanged elsewhere (68 passed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a mandatory `## AI Agent Notes` section to the default template, wrapped in HTML markers (`<!-- amos:ai-notes-begin -->` / `<!-- amos:ai-notes-end -->`) so amos tooling can find and update the section safely without risking the rest of the body. Motivates the section explicitly: agent-facing context (exact error strings, file paths, ruled-out approaches, hidden invariants) that doesn't belong in the human-readable Description/Context but is load-bearing for any agent picking the issue up later. Also spells out the rule for project-specific templates: follow the project's sections verbatim, but append an AI Agent Notes section if the template doesn't already include one — the section is the contract between human-filed issues and agents, and it's the same shape as the migrated content from existing plan-file bodies. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iles A remote-first project can legitimately have zero local plan files — every issue, milestone, and relationship lives in GitHub. The previous check bailed on any command besides Milestones / SyncEdges when no local blocks were present, which broke `next`, `blocked`, `orphans`, and `graph` for fully-migrated projects. Reverse the flag: only commands that genuinely need local state (`validate`, the default DAG dump) require at least one local block. Everything else falls through and pulls its nodes from the adapter. Surfaced while deleting streamlib's entire plan/ directory after migrating every edge and every AI-notes body to GitHub issues. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Only four reference kinds map to native GitHub relationships (blocked_by, blocks, sub_issue_of, duplicate). Everything else — "exposed by", "surfaced by", "follow-up to", "see also", "related to" — is free-text context with no native equivalent, and calling it out at all is usually noise the next agent has to mentally filter. If a reference doesn't affect work order, don't include it. Rule of thumb spelled out: if a reference doesn't fit the four-row table, it's probably not a relationship worth calling out. Native relations are load-bearing for `amos next` / `amos blocked`; soft refs add cognitive overhead without gating anything. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitHub exposes three repo-level issue types — Bug, Feature, Task — as a first-class field distinct from labels. `gh issue create` doesn't support setting them, so amos now applies the type via the `updateIssueIssueType` GraphQL mutation right after creation. - `IssueSpec::issue_type: Option<String>` — case-insensitive match against the repo's configured types. Omit to leave unset. - `GhAdapter::create_issue` looks up the repo's types on demand (one GraphQL call) and resolves the name to an ID before firing the mutation. - main.rs parses `issue_type` from the spec JSON. - The `amos-file` skill now has a Step 4.5 for type inference with conventional-commit heuristics (fix→Bug, feat→Feature, everything else→Task) and an AskUserQuestion fallback when confidence is low. - Draft gate + JSON spec shapes updated to include the type field. Doesn't backfill existing issues — types are a creation-time concern that's easy to set later per-issue via `gh api graphql` if needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Two related workflow fixes for amos projects:
amos milestones/next/blocked/graph. Every command now enumerates from the adapter (GitHub), and plan files become optional AI-notes overlays.amos-fileskill +amos issue-createsubcommand. From short natural-language intent, drafts a well-shaped issue following the project's template (docs/issue-template.mdor.github/ISSUE_TEMPLATE/*.md), infers milestone and labels with anAskUserQuestionfallback when confidence is low, extracts explicit relationships, and creates the issue atomically with nativeblockedBy/blocking/parentedges applied.Also included:
amos sync-edges— one-time migration that pushes existing plan-fileblocked_by:/blocks:frontmatter up to native GitHub relationships. Idempotent; safe to re-run.amos-nextStep 7 now detects every issue the branch addresses (primary + commit-messageCloses #N+ branch name) so merges auto-close the full set, not just the primary issue.list_milestones,list_nodes_in_milestone,add_relationship,create_issue(default no-op/error impls — non-GitHub adapters are untouched and forward-compatible).GhAdapter::with_detected_repo— auto-detectsowner/namefrom the scan root's git remote.Motivation
Pre-change behavior required a local
plan/N-slug.mdfor every issue you wanted amos to see. Two-source-of-truth trap: file an issue in GitHub, it doesn't show up inamos next, no warning. Concretely observed on streamlib: 6 open issues in the focused milestone reportedopen: 0, hiding the next unit of work.Filing issues also required hand-authoring the full template every time. That's friction we can remove — the template rarely changes, milestone inference is usually obvious, and the rare ambiguous cases are exactly when
AskUserQuestionshines. The skill drafts; the user approves the whole package in one step; the binary creates the issue + applies labels/milestone/relationships atomically.Design
Adaptermethods with empty default impls —list_milestones,list_nodes_in_milestone,add_relationship,create_issue. Non-GitHub adapters are untouched.gh api graphql/gh issue create. Detectsowner/namefrom the scan root's git remote so no new configuration is required.(blocked, blocker)form (so mirror declarations don't push twice), and callsaddBlockedBy. "Already exists" responses are treated as success, making the operation idempotent.amos-fileskill produces a JSONIssueSpec(title, body, milestone, labels, blocked_by, blocks, sub_issue_of) and pipes it to the binary. Binary doesgh issue createthen applies native relationships in a single pass. Partial relationship failures are reported to stderr; the issue exists either way.amos-next. Grep the branch's commits forCloses / Fixes / Resolves #N, combine with the primary issue and branch-name detection, emit oneCloses #Nper line in the PR body.Test plan
cargo test— 68 passed (11 new: remote URL parsing, adapter-node JSON mapping, trait-default fallbacks, registry routing, empty-title rejection).cargo clippy— no new warnings introduced by this PR.amos milestonesshows accurate counts (Polyglot SDK Realignment fixed: 6 open / 3 done, matching GitHub).amos nextin the focused milestone enumerates the 6 unplanned issues that were previously invisible.amos sync-edges --dry-runreports 123 unique edges (140 raw, 17 mirror dedups).amos sync-edgesapplied all 123; zero failures.blockedByfor every source issue and diffed against the snapshot — zero missing / zero extra.amos issue-createsubcommand: edge cases (empty title, malformed JSON, missing scheme) route cleanly.Breaking changes
None. Existing plan-file edges are still read and merged. Projects that haven't migrated keep working.
Follow-ups (not in this PR)
sync-edgesand verify, delete the plan-file DAG code path.add_relationship(currently ~2 GraphQL calls per edge — acceptable at this scale).amos-fileonce any project uses GitHub's sub-issue feature.🤖 Generated with Claude Code