diff --git a/.agents/learnings/README.md b/.agents/learnings/README.md new file mode 100644 index 000000000..b612471d7 --- /dev/null +++ b/.agents/learnings/README.md @@ -0,0 +1,33 @@ +# Agent Learnings + +This directory contains durable, repository-specific constraints learned from completed agent runs. It is an evidence +log, not a scratchpad or a replacement for `AGENTS.md`. + +Agents should consult relevant entries before changing or reviewing the affected area. Rules that apply broadly and +remain stable should be promoted to `AGENTS.md` through a normal pull request. + +## Admission Criteria + +A learning must: + +- Link to the source run and the issue or pull request that supplied evidence. +- Describe a repeatable repository constraint, not a one-off implementation. +- Explain how the evidence changes a future implementation or review decision. +- Avoid credentials, customer data, internal-only links, and copied user data. +- Be submitted and reviewed through the normal pull request process. + +Do not record style preferences, speculative advice, or conclusions based only on an agent's own output. + +## Format + +```markdown +# Actionable rule + +- **Source run:** +- **Source issue or PR:** +- **Affected area:** + +State the durable constraint and the action a future agent should take. + +Explain the evidence, the previous failure mode, and why the rule generalizes. +``` diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index b92bbba08..b185f0812 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,73 +1,152 @@ name: Bug Report -description: Report a bug or unexpected behavior +description: Report reproducible unexpected behavior in the AgentCore CLI +title: '[BUG] ' labels: ['bug'] body: - type: markdown attributes: value: | - Thanks for taking the time to report a bug. Please fill out the sections below so we can reproduce and fix the issue. + Include a minimal reproduction and exact environment details. Remove + credentials, tokens, account IDs, customer data, and other sensitive + information from commands, configuration, and logs. + + - type: checkboxes + id: checks + attributes: + label: Before submitting + options: + - label: I searched existing issues and did not find a duplicate. + required: true + - label: I tested with the latest available AgentCore CLI release. + required: true + - label: I removed credentials and sensitive data from this report. + required: true - type: textarea id: description attributes: label: Description - description: A clear and concise description of the bug. - placeholder: Describe what happened... + description: Describe the incorrect behavior and its impact. + placeholder: What happened, and what does it prevent you from doing? + validations: + required: true + + - type: input + id: cli-version + attributes: + label: CLI version + description: Output of `agentcore --version`. + placeholder: '1.2.3' + validations: + required: true + + - type: input + id: node-version + attributes: + label: Node.js version + description: Output of `node --version`. + placeholder: 'v22.17.0' + validations: + required: true + + - type: dropdown + id: installation-method + attributes: + label: Installation method + options: + - npm global install + - npx + - Built from source + - Package tarball + - Other + validations: + required: true + + - type: input + id: operating-system + attributes: + label: Operating system + description: Include the operating system name, version, and architecture. + placeholder: 'macOS 15.5 arm64' + validations: + required: true + + - type: input + id: aws-region + attributes: + label: AWS Region + description: Region used when the problem occurred, or `N/A` for local-only behavior. + placeholder: 'us-west-2' + validations: + required: true + + - type: dropdown + id: resource-dependency + attributes: + label: Resource dependency + description: Does the reproduction require live AWS resources? + options: + - No, it reproduces locally + - Yes, it requires live AWS resources + - Both local and live AWS behavior are affected + - Unknown validations: required: true - type: textarea id: steps attributes: - label: Steps to Reproduce - description: Steps to reproduce the behavior. + label: Minimal reproduction + description: | + Provide the smallest complete sequence that reproduces the problem, + including project setup and commands. Use placeholders for identifiers. placeholder: | - 1. Run `agentcore ...` - 2. Select ... - 3. Observe ... + 1. Create a project with `agentcore create ...` + 2. Add this minimal configuration: ... + 3. Run `agentcore ...` + 4. Observe ... + render: shell validations: required: true - type: textarea id: expected attributes: - label: Expected Behavior - description: What you expected to happen. + label: Expected behavior + description: State the exact result you expected. validations: required: true - type: textarea id: actual attributes: - label: Actual Behavior - description: What actually happened. + label: Actual behavior and error output + description: Include the complete relevant error and stack trace after removing sensitive data. + render: shell validations: required: true - - type: input - id: cli-version - attributes: - label: CLI Version - description: Output of `agentcore --version` - placeholder: '1.0.0' - validations: - required: false - - type: dropdown - id: os + id: frequency attributes: - label: Operating System + label: Reproduction frequency options: - - macOS - - Windows - - Linux + - Every time + - Intermittently + - Once + - Unknown validations: required: true + - type: input + id: last-working-version + attributes: + label: Last known working version + description: If this is a regression, provide the last CLI version that worked. + placeholder: 'N/A or 1.2.2' + - type: textarea id: context attributes: - label: Additional Context - description: Any other context, screenshots, or logs that might help. - validations: - required: false + label: Additional context + description: Add sanitized configuration, screenshots, or related issue links. diff --git a/.github/workflows/auto-close-unverified-bugs.yml b/.github/workflows/auto-close-unverified-bugs.yml new file mode 100644 index 000000000..6d4eb608a --- /dev/null +++ b/.github/workflows/auto-close-unverified-bugs.yml @@ -0,0 +1,139 @@ +name: Auto Close Unverified Bugs + +on: + schedule: + - cron: '0 14 * * 1-5' + workflow_dispatch: + inputs: + dry_run: + description: Log actions without changing issues + required: false + default: true + type: boolean + +permissions: + contents: read + issues: write + +jobs: + close-unverified-bugs: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Process issues awaiting reporter information + uses: actions/github-script@v9 + env: + LABEL_NAME: autoclose in 7 days + DAYS_TO_WAIT: '7' + MANUAL_DRY_RUN: ${{ inputs.dry_run || false }} + with: + script: | + const labelName = process.env.LABEL_NAME; + const waitMs = + Number(process.env.DAYS_TO_WAIT) * 24 * 60 * 60 * 1000; + const dryRun = + context.eventName === "workflow_dispatch" && + process.env.MANUAL_DRY_RUN === "true"; + + const candidates = await github.paginate( + github.rest.issues.listForRepo, + { + owner: context.repo.owner, + repo: context.repo.repo, + state: "open", + labels: labelName, + per_page: 100, + }, + ); + + const issues = candidates.filter((issue) => !issue.pull_request); + core.info(`Found ${issues.length} issue(s) with "${labelName}"`); + + for (const issue of issues) { + const events = await github.paginate( + github.rest.issues.listEvents, + { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + per_page: 100, + }, + ); + + const labelEvents = events + .filter( + (event) => + event.event === "labeled" && + event.label?.name === labelName, + ) + .sort( + (left, right) => + new Date(right.created_at) - new Date(left.created_at), + ); + + if (labelEvents.length === 0) { + core.warning( + `Skipping #${issue.number}: label event was not found`, + ); + continue; + } + + const labeledAt = new Date(labelEvents[0].created_at); + const comments = await github.paginate( + github.rest.issues.listComments, + { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + since: labeledAt.toISOString(), + per_page: 100, + }, + ); + + const reporterResponded = comments.some( + (comment) => + comment.user?.login === issue.user?.login && + new Date(comment.created_at) > labeledAt, + ); + + if (reporterResponded) { + core.info( + `Reporter responded on #${issue.number}; removing label`, + ); + if (!dryRun) { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + name: labelName, + }); + } + continue; + } + + if (Date.now() - labeledAt.getTime() < waitMs) { + core.info(`#${issue.number} is still within the waiting period`); + continue; + } + + core.info(`Closing #${issue.number} after the waiting period`); + if (!dryRun) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: + "This issue was automatically closed because the " + + "requested reproduction details were not provided within " + + "7 days. Add the missing information in a new issue if " + + "the problem persists.", + }); + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + state: "closed", + state_reason: "not_planned", + }); + } + } diff --git a/AGENTS.md b/AGENTS.md index 4d4627610..b8a1c37c6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,6 +2,12 @@ CLI tool for Amazon Bedrock AgentCore. Manages agent infrastructure lifecycle. +## Learned Constraints + +Repository-specific constraints derived from completed agent runs live in `.agents/learnings/`. Consult relevant entries +before changing or reviewing an affected area. New learnings require evidence and normal pull request review; see +`.agents/learnings/README.md`. + ## Package Structure ```