Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
63c27e4
docs: add design spec for triage prerequisites action (#401)
ralphbean Jun 11, 2026
ba99ae3
docs: add implementation plan for triage prerequisites action (#401)
ralphbean Jun 11, 2026
9a35c91
feat(config): add create_issues allowlist config (#401)
ralphbean Jun 11, 2026
d4a394e
refactor: update NewOrgConfig/NewPerRepoConfig callers for create_iss…
ralphbean Jun 11, 2026
e492ac7
feat(schema): replace blocked with prerequisites action (#401)
ralphbean Jun 11, 2026
b2055cb
feat(triage): replace blocked action with prerequisites in agent prom…
ralphbean Jun 11, 2026
c48a832
docs: document prerequisites action and create_issues config (#401)
ralphbean Jun 11, 2026
3a44b0c
feat(triage): handle prerequisites action in post-script (#401)
ralphbean Jun 11, 2026
6f79d87
fix(triage): correct label name in agent prompt and remove dead code …
ralphbean Jun 11, 2026
080368c
fix(triage): update post-triage tests for prerequisites action (#401)
ralphbean Jun 11, 2026
11bae49
fix(triage): update schema validation tests for prerequisites action …
ralphbean Jun 12, 2026
e57f10a
fix(triage): address review feedback on prerequisites action (#401)
ralphbean Jun 12, 2026
2e040b5
chore(skills): add e2e-health skill
ralphbean Jun 15, 2026
7c40a70
fix(skills): escape example link in e2e-health SKILL.md
ralphbean Jun 15, 2026
162dce2
fix(skills): address review feedback on e2e-health skill
ralphbean Jun 15, 2026
80a414d
fix: widen CSMA jitter after rate-limit reset to prevent thundering herd
ralphbean Jun 15, 2026
22be06d
feat(harness): add remote harness agent discovery via forge API (ADR-…
ggallen Jun 16, 2026
61f467d
test: add Phase 2 integration tests for ADR-0045 forge-portable harne…
ggallen Jun 16, 2026
3305c1a
feat(harness): add Lint() diagnostic method for non-fatal harness war…
ggallen Jun 16, 2026
ded059b
fix(#2130): mint fresh tokens for status comments on demand
ggallen Jun 16, 2026
3c9f0db
Merge pull request #2304 from fullsend-ai/fix/csma-jitter-window
ralphbean Jun 16, 2026
7249b34
fix(skills): remove markdown link syntax from e2e-health example table
ralphbean Jun 16, 2026
df020f5
Merge pull request #2301 from fullsend-ai/add-e2e-health-skill
ralphbean Jun 16, 2026
3ae6f72
fix(#2343): add post-reset spread to _github_csma_sleep_after_rate_limit
fullsend-ai-coder[bot] Jun 16, 2026
966abbf
Merge pull request #2344 from fullsend-ai/agent/2343-csma-spread-rate…
ralphbean Jun 16, 2026
d988d32
merge: resolve conflict with main in admin.go
ralphbean Jun 16, 2026
a24ffd1
style: gofmt config.go after merge
ralphbean Jun 16, 2026
d6988a9
Merge pull request #2299 from ggallen/worktree-fix-2130-status-token
ggallen Jun 16, 2026
515e49b
Merge pull request #2321 from ggallen/worktree-phase2-pr6
ggallen Jun 16, 2026
133ed6e
Merge pull request #2197 from fullsend-ai/rbean/401-triage-decompose-…
ralphbean Jun 16, 2026
6832b14
Merge pull request #2327 from fullsend-ai/worktree-adr-0045-phase3-pr2
ggallen Jun 16, 2026
32f73a4
Merge pull request #2322 from ggallen/worktree-investigate-adr-0045
ggallen Jun 16, 2026
dd9fc10
perf(#2351): batch path-existence checks via Git Trees API
fullsend-ai-coder[bot] Jun 16, 2026
96eb471
Add QualityFlow output for GH-25 [skip ci]
Jun 17, 2026
2b18dc9
Add STP output for GH-25 [skip ci]
Jun 17, 2026
3926ec6
Add QualityFlow STP review output for GH-25 [skip ci]
Jun 17, 2026
e6c36b9
Add STD output for GH-25 [skip ci]
Jun 17, 2026
c7daf1e
Add QualityFlow STD review for GH-25 [skip ci]
Jun 17, 2026
67bf00f
Refine STD for GH-25: resolve function name mismatches and priority d…
Jun 17, 2026
3eab2c0
Add test output for GH-25 [skip ci]
Jun 17, 2026
1386329
Add QualityFlow tests for GH-25
guyoron1 Jun 17, 2026
e35c078
Add QualityFlow output for GH-25 [skip ci]
Jun 18, 2026
7d80250
Add STP output for GH-25 [skip ci]
Jun 18, 2026
788d607
Add QualityFlow STP review for GH-25 [skip ci]
Jun 18, 2026
5929d8e
Add QualityFlow STD review output for GH-25 [skip ci]
Jun 18, 2026
cf5c405
Add QualityFlow STD output for GH-25 [skip ci]
Jun 18, 2026
b097cb4
Add test output for GH-25 [skip ci]
Jun 18, 2026
0db5efc
Add QualityFlow tests for GH-25
guyoron1 Jun 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/reusable-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,4 @@ jobs:
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
status-repo: ${{ inputs.source_repo }}
status-number: ${{ fromJSON(inputs.event_payload).issue.number }}
status-token: ${{ steps.app-token.outputs.token }}
mint-url: ${{ inputs.mint_url }}
2 changes: 1 addition & 1 deletion .github/workflows/reusable-fix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,4 @@ jobs:
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
status-repo: ${{ inputs.source_repo }}
status-number: ${{ steps.context.outputs.pr_number }}
status-token: ${{ steps.app-token.outputs.token }}
mint-url: ${{ inputs.mint_url }}
2 changes: 1 addition & 1 deletion .github/workflows/reusable-retro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,4 @@ jobs:
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
status-repo: ${{ inputs.source_repo }}
status-number: ${{ fromJSON(inputs.event_payload).pull_request.number || fromJSON(inputs.event_payload).issue.number }}
status-token: ${{ steps.app-token.outputs.token }}
mint-url: ${{ inputs.mint_url }}
2 changes: 1 addition & 1 deletion .github/workflows/reusable-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,4 @@ jobs:
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
status-repo: ${{ inputs.source_repo }}
status-number: ${{ fromJSON(inputs.event_payload).pull_request.number || fromJSON(inputs.event_payload).issue.number }}
status-token: ${{ steps.app-token.outputs.token }}
mint-url: ${{ inputs.mint_url }}
2 changes: 1 addition & 1 deletion .github/workflows/reusable-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,4 @@ jobs:
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
status-repo: ${{ inputs.source_repo }}
status-number: ${{ fromJSON(inputs.event_payload).issue.number }}
status-token: ${{ steps.app-token.outputs.token }}
mint-url: ${{ inputs.mint_url }}
3 changes: 0 additions & 3 deletions CLAUDE.md

This file was deleted.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ This is not a product spec. It's an evolving exploration of a hard problem space
- [Vertex AI Inference Provisioning](docs/plans/vertex-inference-provisioning.md) — Provisioning and configuration for Vertex AI inference endpoints
- [ADR-0045 Forge-Portable Harness Schema — Phase 1](docs/plans/adr-0045-forge-portable-harness-phase1.md) — Implementation plan for ADR-0045 forge-portable harness schema (Phase 1)
- [ADR-0045 Forge-Portable Harness Schema — Phase 2](docs/plans/adr-0045-forge-portable-harness-phase2.md) — Implementation plan for ADR-0045 Phase 2: adopt new schema fields across install, scaffold, and lock flows
- [ADR-0045 Forge-Portable Harness Schema — Phase 3](docs/plans/adr-0045-forge-portable-harness-phase3.md) — Implementation plan for ADR-0045 Phase 3: deprecate config.yaml agents block, add Lint() diagnostics, migrate to harness-first discovery
- [ADR-0046 Drift Scanner](docs/plans/2026-03-06-adr46-drift-scanner.md) — Implementation plan for ADR-0046 drift detection tool
- **[docs/guides/](docs/guides/)** — Practical how-to documentation for administrators and developers (see [ADR 0023](docs/ADRs/0023-user-documentation-structure.md))
- **[docs/ADRs/](docs/ADRs/)** — Architecture Decision Records for crystallizing specific decisions (see [ADR 0001](docs/ADRs/0001-use-adrs-for-decision-making.md))
Expand Down
39 changes: 28 additions & 11 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ inputs:
status-number:
description: Issue/PR number for status comments (optional).
default: ""
mint-url:
description: >-
Mint service URL for on-demand status comment tokens. When set, the
binary mints a fresh short-lived token before each status API call
instead of using a static status-token.
default: ""
status-token:
description: Token for status comments (defaults to GH_TOKEN env var).
description: >-
DEPRECATED — use mint-url instead. Static GitHub token for status
comments. Ignored when mint-url is set.
default: ""

runs:
Expand Down Expand Up @@ -363,26 +371,31 @@ runs:
STATUS_RUN_URL: ${{ inputs.run-url }}
STATUS_REPO: ${{ inputs.status-repo }}
STATUS_NUMBER: ${{ inputs.status-number }}
MINT_URL: ${{ inputs.mint-url }}
STATUS_TOKEN: ${{ inputs.status-token }}
run: |
set -euo pipefail
if [[ -n "${STATUS_TOKEN}" ]]; then
echo "::add-mask::${STATUS_TOKEN}"
fi
FULLSEND_DIR="${FULLSEND_DIR:-${GITHUB_WORKSPACE}}"
TARGET_REPO="${TARGET_REPO:-${GITHUB_WORKSPACE}/target-repo}"
mkdir -p "${GITHUB_WORKSPACE}/output"
# SECURITY: Never expose --no-post-script as a workflow input.
# Post-scripts enforce secret scanning, protected-path blocks,
# and review-downgrade controls. Skipping them in CI bypasses
# all post-push security gates.
if [[ -n "${STATUS_TOKEN}" ]]; then
echo "::add-mask::${STATUS_TOKEN}"
fi
STATUS_FLAGS=()
if [[ -n "${STATUS_REPO}" && -n "${STATUS_NUMBER}" ]]; then
STATUS_FLAGS+=(--status-repo "${STATUS_REPO}" --status-number "${STATUS_NUMBER}")
if [[ -n "${STATUS_RUN_URL}" ]]; then
STATUS_FLAGS+=(--run-url "${STATUS_RUN_URL}")
fi
if [[ -n "${MINT_URL}" ]]; then
STATUS_FLAGS+=(--mint-url "${MINT_URL}")
fi
if [[ -n "${STATUS_TOKEN}" ]]; then
echo "::warning::status-token is deprecated; use mint-url instead"
STATUS_FLAGS+=(--status-token "${STATUS_TOKEN}")
fi
fi
Expand All @@ -393,10 +406,12 @@ runs:
"${STATUS_FLAGS[@]+"${STATUS_FLAGS[@]}"}"

- name: Finalize orphaned status comment
if: always() && inputs.agent != '__install_only__' && inputs.status-repo != '' && inputs.status-number != ''
if: always() && inputs.agent != '__install_only__' && inputs.status-repo != '' && inputs.status-number != '' && (inputs.mint-url != '' || inputs.status-token != '')
shell: bash
env:
MINT_URL: ${{ inputs.mint-url }}
STATUS_TOKEN: ${{ inputs.status-token }}
AGENT: ${{ inputs.agent }}
STATUS_REPO: ${{ inputs.status-repo }}
STATUS_NUMBER: ${{ inputs.status-number }}
RUN_ID: ${{ github.run_id }}
Expand All @@ -405,17 +420,19 @@ runs:
JOB_STATUS: ${{ job.status }}
run: |
set -euo pipefail
if [[ -n "${STATUS_TOKEN}" ]]; then
echo "::add-mask::${STATUS_TOKEN}"
fi
# When the fullsend process is hard-killed (SIGKILL, OOM, segfault),
# the deferred PostCompletion call never runs and the status comment
# remains in "Started" state. This step runs unconditionally (if:
# always()) to detect and finalize orphaned comments. See #2149.
TOKEN="${STATUS_TOKEN:-${GITHUB_TOKEN:-}}"
if [[ -z "${TOKEN}" ]]; then
echo "::warning::No token available for status comment reconciliation"
exit 0
RECONCILE_FLAGS=(--repo "${STATUS_REPO}" --number "${STATUS_NUMBER}" --run-id "${RUN_ID}")
if [[ -n "${MINT_URL}" ]]; then
RECONCILE_FLAGS+=(--mint-url "${MINT_URL}" --role "${AGENT}")
elif [[ -n "${STATUS_TOKEN}" ]]; then
RECONCILE_FLAGS+=(--token "${STATUS_TOKEN}")
fi
echo "::add-mask::${TOKEN}"
RECONCILE_FLAGS=(--repo "${STATUS_REPO}" --number "${STATUS_NUMBER}" --run-id "${RUN_ID}" --token "${TOKEN}")
if [[ -n "${RUN_URL}" ]]; then
RECONCILE_FLAGS+=(--run-url "${RUN_URL}")
fi
Expand Down
14 changes: 7 additions & 7 deletions docs/ADRs/0045-forge-portable-harness-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ agent definition `.md` file). `agent` describes *how* the agent behaves;
`role` describes *what function* the agent serves in the pipeline; `slug`
describes *who* the agent authenticates as. During Phase 1-2, `role` and
`slug` are optional — `Validate()` does not require them. In Phase 3,
`Validate()` emits warnings when `role` is missing. In Phase 4,
`Validate()` requires `role`.
`Validate()` continues to allow missing `role`, but `Lint()` emits
warnings when `role` is missing. In Phase 4, `Validate()` requires
`role`.

`base` references another harness file whose fields serve as defaults for
this harness. Any field set in the child overrides the corresponding base
Expand Down Expand Up @@ -516,11 +517,10 @@ func (h *Harness) ResolveForge(platform string) error { ... }
Note: `role`/`slug` becoming required is independent of the `forge:`
section — a harness that only targets one platform still needs `role`
and `slug` but does not need `forge:`.
Implementation note: the current `Validate()` method returns hard errors
only — there is no warning/advisory path. Phase 3 will need a separate
`Lint()` method or log-level warnings to emit non-fatal diagnostics
without breaking existing callers that treat any `Validate()` error as
a hard stop.
Implementation note: `Validate()` returns hard errors only. Phase 3
adds a separate `Lint()` method that returns non-fatal `[]Diagnostic`
warnings without breaking existing callers that treat any `Validate()`
error as a hard stop.

4. **Phase 4 (remove):** Require `role` in all harness files. Remove the
`agents:` block from config.yaml entirely. Agent identity and
Expand Down
33 changes: 32 additions & 1 deletion docs/agents/triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,45 @@ outcome and the post-script applies the corresponding label.
| `ready-to-code` | The issue is fully specified and low-risk (bug, documentation, performance). Triggers the [code agent](code.md). |
| `triaged` | The issue is fully specified but is a feature or other category that requires human prioritization before coding. |
| `duplicate` | The issue duplicates an existing one. The agent identified the original and the post-script closes the issue. |
| `blocked` | The issue depends on another issue or external condition. The agent identified the blocker. |
| `blocked` | The issue depends on prerequisites — existing issues/PRs or newly created upstream issues. The agent identified or created the blockers. |
| `question` | The issue is a support request or question, not an actionable bug or feature. The agent attempted to answer it. |

The `issue-labels` skill may also apply contextual labels (e.g., `area/api`,
`kind/bug`) but these are informational — they do not control agent behavior.

## Configuration and extension

### Cross-repo issue creation

The triage agent can create prerequisite issues in other repositories when it
identifies upstream dependencies that don't have tracking issues yet. This is
controlled by the `create_issues` section in `config.yaml`:

```yaml
create_issues:
allow_targets:
orgs:
- my-org
repos:
- upstream-org/specific-repo
```

**Defaults:** At install time, fullsend populates this with your org (in org mode)
or your repo (in per-repo mode), plus `fullsend-ai/fullsend` as an upstream target.

**When to expand the allowlist:** If your project depends on libraries or services
in other GitHub orgs and you want the triage agent to automatically file
prerequisite issues there, add those orgs or repos to `allow_targets`.

**When to restrict the allowlist:** If you don't want agents creating issues
outside your org, remove entries. If `allow_targets` is empty, automatic
prerequisite creation is disabled entirely — the agent will still identify
the dependency and include a draft issue body in its comment for a human to
file manually.

The source repo (where triage is running) is always implicitly allowed
regardless of the allowlist.

### Skill: `issue-labels`

The triage agent includes a built-in `issue-labels` skill that discovers your
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ ADR 0002: [Building block 3](ADRs/0002-initial-fullsend-design.md#3-label-state-

### 4. triage agent runtime

Runs triage from issue `title`/`body` + GitHub-native attachments only; each run starts with **`duplicate`** and other reset labels cleared; duplicate detection, blocking dependency detection (cross-repo), readiness, reproducibility, test handoff; can close as duplicate again if still a match, or label **`blocked`** when progress depends on another open issue or PR.
Runs triage from issue `title`/`body` + GitHub-native attachments only; each run starts with **`duplicate`** and other reset labels cleared; duplicate detection, prerequisite detection (cross-repo), readiness, reproducibility, test handoff; can close as duplicate again if still a match, label **`blocked`** when progress depends on another open issue or PR, or create upstream prerequisite issues when no tracking issue exists (controlled by `create_issues.allow_targets` config).
ADR 0002: [Building block 4](ADRs/0002-initial-fullsend-design.md#4-triage-agent-runtime).

### 5. Duplicate / similarity search
Expand Down
5 changes: 3 additions & 2 deletions docs/guides/dev/cli-internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fullsend
│ ├── --run-url <url> # CI/CD run URL for status comments
│ ├── --status-repo <owner/repo> # Repository for status comments
│ ├── --status-number <int> # Issue/PR number for status comments
│ └── --status-token <token> # Token for status comments (default: GH_TOKEN)
│ └── --mint-url <url> # Mint service URL for on-demand status tokens
├── fetch-skill <url> # Fetch a skill at runtime (in-sandbox)
├── scan # Run security scanner on input/output
│ ├── input # Scan event payload for prompt injection
Expand All @@ -74,7 +74,8 @@ fullsend
├── --run-url <url> # Workflow run URL (optional)
├── --sha <string> # Commit SHA (optional)
├── --reason <string> # Termination reason: terminated or cancelled (default: terminated)
└── --token <token> # GitHub token (default: $GITHUB_TOKEN)
├── --mint-url <url> # Mint service URL for on-demand token (default: $FULLSEND_MINT_URL)
└── --role <string> # Agent role for minting (required with --mint-url)
```

### Command Decomposition
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/user/bugfix-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Every push to a PR in the review stage triggers a new review round. This means `
The triage agent:

1. **Checks for duplicates.** Searches existing issues by title, body, and metadata. If it finds a match with high confidence, it labels `duplicate`, posts a comment linking the canonical issue, and closes this one.
2. **Checks for blocking dependencies.** Searches for open issues or PRs (in this repo or upstream) that must be resolved before work can start. If a blocker is found, it labels `blocked` and posts a comment linking to the blocking issue or PR. On re-triage, it checks whether existing blockers have been resolved.
2. **Checks for blocking dependencies.** Searches for open issues or PRs (in this repo or upstream) that must be resolved before work can start. If a prerequisite is found, it labels `blocked` and posts a comment linking to it. When no upstream tracking issue exists, the triage agent can also create one in the upstream repo (controlled by `create_issues.allow_targets` in config). On re-triage, it checks whether existing prerequisites have been resolved.
3. **Checks information sufficiency.** If the issue body is missing steps to reproduce, expected behavior, or other critical details, it labels `needs-info` and posts a comment explaining what's missing.
4. **Produces a test artifact.** When possible, writes a failing test case aligned with the repo's test framework.
5. **Hands off.** Labels `ready-to-code` with a summary comment.
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/user/running-agents-locally.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ target issue/PR. These flags mirror what the CI workflows pass automatically:
| `--run-url` | URL of the CI/CD run shown in the status comment |
| `--status-repo` | Repository (`owner/repo`) to post status comments on |
| `--status-number` | Issue or PR number for status comments |
| `--status-token` | Token for posting comments (defaults to `GH_TOKEN`) |
| `--mint-url` | Mint service URL for on-demand status comment tokens (default: `$FULLSEND_MINT_URL`) |

Example:

Expand Down
Loading
Loading