From 0fc466a06beb9712bab44103eb8abba4f0e5694b Mon Sep 17 00:00:00 2001 From: "seahaven-openswe[bot]" <296972425+seahaven-openswe[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 16:29:35 -0400 Subject: [PATCH] docs: add per-repo AGENTS.md templates for stack-specific conventions (#126) Refs: #114 Co-authored-by: amoussa1229 <166072409+amoussa1229@users.noreply.github.com> --- README.md | 2 +- docs/repo-conventions/AGENTS.md.aws | 31 +++++++++++ docs/repo-conventions/AGENTS.md.cdk | 79 +++++++++++++++++++++++++++++ docs/repo-conventions/AGENTS.md.ec2 | 48 ++++++++++++++++++ docs/repo-conventions/AGENTS.md.sam | 57 +++++++++++++++++++++ docs/repo-conventions/README.md | 40 +++++++++++++++ 6 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 docs/repo-conventions/AGENTS.md.aws create mode 100644 docs/repo-conventions/AGENTS.md.cdk create mode 100644 docs/repo-conventions/AGENTS.md.ec2 create mode 100644 docs/repo-conventions/AGENTS.md.sam create mode 100644 docs/repo-conventions/README.md diff --git a/README.md b/README.md index d3e666ca..8ae2cd71 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ GitHub operations are performed with `GH_TOKEN=dummy gh` inside the sandbox, bac Open SWE gathers context from two sources: -- **`AGENTS.md`** — If the repo contains an `AGENTS.md` file at the root, it's read from the sandbox and injected into the system prompt. This is your repo-level equivalent of Stripe's rule files: encoding conventions, testing requirements, and architectural decisions that every agent run should follow. +- **`AGENTS.md`** — If the repo contains an `AGENTS.md` file at the root, it's read from the sandbox and injected into the system prompt. This is your repo-level equivalent of Stripe's rule files: encoding conventions, testing requirements, and architectural decisions that every agent run should follow. Reference templates for stack-specific conventions (AWS, SAM, CDK, EC2) live in [`docs/repo-conventions/`](docs/repo-conventions/). - **Source context** — The full Linear issue (title, description, comments) or Slack thread history is assembled and passed to the agent, so it starts with rich context rather than discovering everything through tool calls. ### 5. Orchestration — Subagents + Middleware diff --git a/docs/repo-conventions/AGENTS.md.aws b/docs/repo-conventions/AGENTS.md.aws new file mode 100644 index 00000000..ce244b2a --- /dev/null +++ b/docs/repo-conventions/AGENTS.md.aws @@ -0,0 +1,31 @@ +# AGENTS.md — AWS conventions + +These rules apply to any repository that deploys to AWS (SAM, CDK, or plain +CloudFormation). Place this file at the repo root as `AGENTS.md`. When the repo +also targets a specific framework (SAM, CDK), supplement this file with the +framework-specific template from `docs/repo-conventions/AGENTS.md.` +and merge both into a single `AGENTS.md`. + +## Infrastructure as Code principles + +- **SAM is the default** for new serverless workloads unless the task explicitly + calls for CDK or raw CloudFormation. +- **Lambda defaults:** prefer Python 3.12 runtime, ARM64 architecture, 128 MB + memory (raise only when needed with evidence), and 30-second timeout unless + the task requires longer. +- **Exact-pin all CDK library versions.** Never use `*` or `^` ranges in + `package.json` for `aws-cdk-lib`, `aws-cdk`, `constructs`, or any + `@aws-cdk/*` package. Pin to an exact version (e.g. `"2.100.0"`, not + `"^2.100.0"`). +- **Never commit** account IDs, role ARNs, VPC IDs, security group IDs, or any + other deployment-specific identifiers. Use CloudFormation parameters or + context values (`cdk.json` / `cdk.context.json`) with documented defaults. +- **Deploy with least-privilege IAM.** Every Lambda, Step Function, or ECS task + gets its own scoped role. Do not reuse admin or broad-read roles across + resources. + +## Verification + +- Run `cdk synth` (CDK) or `sam build && sam validate` (SAM) before pushing. +- If the repo has a `Makefile` or `package.json` script for synth/validate, use + it instead of the bare command. diff --git a/docs/repo-conventions/AGENTS.md.cdk b/docs/repo-conventions/AGENTS.md.cdk new file mode 100644 index 00000000..66946ea1 --- /dev/null +++ b/docs/repo-conventions/AGENTS.md.cdk @@ -0,0 +1,79 @@ +# AGENTS.md — CDK conventions + +Supplement to `AGENTS.md.aws`. Merge into the repo root `AGENTS.md` alongside +the AWS base conventions. + +## Directory layout + +``` +. +├── bin/ +│ └── .ts # CDK app entrypoint +├── lib/ +│ └── .ts # Stack definitions +├── cdk.json # CDK context + config +├── cdk.context.json # Resolved context values (git-committed) +├── package.json # Exact-pinned CDK dependencies +├── tsconfig.json +└── Makefile # Synth/deploy shortcuts +``` + +## CDK dependencies — exact pins + +```json +{ + "dependencies": { + "aws-cdk-lib": "2.100.0", + "constructs": "10.3.0" + }, + "devDependencies": { + "aws-cdk": "2.100.0", + "typescript": "~5.4.0" + } +} +``` + +- Never use `^` or `*` ranges on CDK packages. All CDK libs (`aws-cdk-lib`, + `aws-cdk`, `constructs`, `@aws-cdk/*`) must be exact-pinned. +- When upgrading CDK, upgrade the CLI (`aws-cdk`) and the lib + (`aws-cdk-lib`) to the same version in a single commit. + +## ARM64 / QEMU build note + +CDK's `Lambda` and `DockerImageFunction` constructs default to `x86_64`. When +targeting ARM64 (`Architecture.ARM_64`), note that building Docker images on +a non-ARM host requires QEMU emulation. For local development, ensure QEMU is +installed: + +```bash +docker run --rm --privileged multiarch/qemu-user-static --reset -p yes +``` + +Agents running in the cloud sandbox may not have QEMU. When ARM64 Docker +builds fail, either switch the Lambda architecture to `X86_64` (if +compatible) or use a pre-built ARM64 image from ECR instead of building in +the sandbox. + +## `overrideLogicalId` — never remove + +CDK's `overrideLogicalId` method forces a deterministic physical ID for a +construct. Removing it on a resource that was previously deployed with one +**forces replacement** — CloudFormation will delete and recreate the resource. + +- **Never remove an existing `overrideLogicalId` call.** If the logical ID + must change, document why in the PR description and confirm the replacement + impact. +- When adding a new `overrideLogicalId`, prefer stable, descriptive names + (e.g. `MyQueueDLQ` over `ResourceABC123`). + +## Build & verify + +```bash +npm run build # tsc compile +cdk synth # Synthesize CloudFormation +cdk diff # Show changes before deploy (do NOT deploy) +``` + +- Run `npm run build && npx cdk synth` before pushing. Do not commit + `cdk.out/`. +- If the repo has a `Makefile` wrapping these, use the Makefile targets. diff --git a/docs/repo-conventions/AGENTS.md.ec2 b/docs/repo-conventions/AGENTS.md.ec2 new file mode 100644 index 00000000..7fc7ff77 --- /dev/null +++ b/docs/repo-conventions/AGENTS.md.ec2 @@ -0,0 +1,48 @@ +# AGENTS.md — EC2 + persistent EBS conventions + +Supplement to `AGENTS.md.aws` (and `AGENTS.md.cdk` when using CDK). Merge into +the repo root `AGENTS.md` alongside the other templates. + +## Persistent EBS volumes + +EC2 instances managed through CDK or CloudFormation should treat EBS volumes +as durable, not disposable. The pattern is: + +### Standalone `Volume` resource with `RETAIN` + +```typescript +import * as ec2 from 'aws-cdk-lib/aws-ec2'; + +const dataVolume = new ec2.CfnVolume(this, 'DataVolume', { + availabilityZone: instance.instanceAvailabilityZone, + size: 100, + volumeType: 'gp3', +}); + +dataVolume.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN); +``` + +- Always create the EBS volume as a **separate `CfnVolume` resource**, not + inline on the instance. +- Set the removal policy to `RETAIN` so the volume survives stack deletion. +- Attach the volume to the instance with a `CfnVolumeAttachment`. + +### Snapshot before an EC2-replacing deploy + +Before any deploy that would replace the EC2 instance (AMI change, user-data +change, instance type change), take a manual snapshot of the attached EBS +volume. The agent should: + +1. Run `cdk diff` to confirm the instance will be replaced. +2. **Stop and ask for confirmation** before proceeding — an instance + replacement with `RETAIN` volumes will detach the volume, but the snapshot + is a safety net. Do not proceed unilaterally. +3. If a snapshot already exists from the same day, reference it rather than + creating a duplicate. + +## Security group rules + +- Never open 0.0.0.0/0 on port 22 (SSH). Use a specific CIDR range or + Systems Manager Session Manager. +- All security group rules must use the narrowest source (specific CIDR or + security group reference). diff --git a/docs/repo-conventions/AGENTS.md.sam b/docs/repo-conventions/AGENTS.md.sam new file mode 100644 index 00000000..92e10666 --- /dev/null +++ b/docs/repo-conventions/AGENTS.md.sam @@ -0,0 +1,57 @@ +# AGENTS.md — SAM conventions + +Supplement to `AGENTS.md.aws`. Merge into the repo root `AGENTS.md` alongside +the AWS base conventions. + +## Directory layout + +``` +. +├── template.yaml # SAM template (single-file or entrypoint) +├── .aws-sam/ # SAM build artifacts (git-ignored) +├── src/ +│ └── / +│ ├── app.py # Lambda handler +│ └── requirements.txt # Per-function dependencies +├── layers/ +│ └── / +│ ├── requirements.txt +│ └── (source files) +├── events/ # Test event payloads +├── samconfig.toml # SAM CLI configuration +└── Makefile # Build/deploy shortcuts +``` + +## Layer `BuildMethod` nesting gotcha + +When a Lambda layer's `ContentUri` points to a directory that contains a +`requirements.txt`, SAM's `python3.12` build method nests the installed +packages under `python/` inside the layer. Do **not** create an extra +`python/` directory inside the layer source — let SAM handle it. That is: + +``` +# Correct — SAM creates python/ for you +MyLayer: + Type: AWS::Serverless::LayerVersion + Properties: + ContentUri: layers/my-layer/ + CompatibleRuntimes: [python3.12] + Metadata: + BuildMethod: python3.12 + +# Wrong — double-nesting breaks imports +MyLayer: + ... + ContentUri: layers/my-layer/python/ # DON'T do this +``` + +## Build & validate + +```bash +sam build # Build all functions and layers +sam validate # Validate the template +sam local invoke ... # Test a single function locally +``` + +- Run `sam build && sam validate` before pushing. Do not commit `.aws-sam/`. +- If the repo has a `Makefile` wrapping these, use the Makefile targets. diff --git a/docs/repo-conventions/README.md b/docs/repo-conventions/README.md new file mode 100644 index 00000000..306be976 --- /dev/null +++ b/docs/repo-conventions/README.md @@ -0,0 +1,40 @@ +# Per-repo AGENTS.md templates + +Reference templates for stack-specific conventions that belong in each target +repo rather than in the shared agent prompt. Both the coding agent and the +deterministic reviewer read `AGENTS.md` from the repo root. + +## How to use these + +For each target repo, merge the applicable templates into a single `AGENTS.md` +at the repo root: + +| Repo uses | Templates to merge | +|---|---| +| SAM + Lambda | `AGENTS.md.aws` + `AGENTS.md.sam` | +| CDK + Lambda | `AGENTS.md.aws` + `AGENTS.md.cdk` | +| CDK + EC2 | `AGENTS.md.aws` + `AGENTS.md.cdk` + `AGENTS.md.ec2` | +| Plain CloudFormation | `AGENTS.md.aws` | + +Strip any convention that does not apply to the specific repo. Do not carry +role ARNs, account IDs, VPC IDs, or other deployment specifics — these +templates keep the principle, not the configuration. + +## Where each convention lives + +| Convention | Channel | Template | +|---|---|---| +| SAM-default; Lambda defaults; exact-pin CDK lib versions | Committed `AGENTS.md` or per-repo dashboard instructions | `AGENTS.md.aws` | +| Never remove `overrideLogicalId` | Committed `AGENTS.md` | `AGENTS.md.cdk` | +| Persistent EBS: standalone `Volume` + `RETAIN`; snapshot before EC2-replacing deploy | Committed `AGENTS.md` | `AGENTS.md.ec2` | +| SAM directory layout + layer `BuildMethod` nesting gotcha | Committed `AGENTS.md` | `AGENTS.md.sam` | +| CDK directory layout + ARM64/QEMU build note | Committed `AGENTS.md` | `AGENTS.md.cdk` | + +## Operator-managed overrides + +Rules that are operator-managed and should not live in the repo belong in the +dashboard's per-repo custom-instructions store (`/dashboard/agents/instructions` +or `/dashboard/api/agent-instructions`). Use this for: +- Temporary deployment freezes +- Repo-specific model or sandbox configuration +- Rules that change with the team, not the code