forgedock 1.0.21 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -80
- package/bin/demo.mjs +386 -0
- package/bin/forgedock.mjs +357 -30
- package/bin/init-detect.mjs +95 -0
- package/bin/runner.mjs +780 -0
- package/commands/cleanup.md +85 -39
- package/commands/deploy-info.md +6 -2
- package/commands/forge-stats.md +1 -1
- package/commands/optimize.md +1 -1
- package/commands/orchestrate.md +320 -26
- package/commands/quality-gate.md +91 -49
- package/commands/review-pr-agents.md +62 -38
- package/commands/review-pr.md +33 -2
- package/commands/scope.md +11 -3
- package/commands/security-audit.md +24 -16
- package/commands/sync-ecosystem.md +2 -2
- package/commands/work-on/build/architect.md +47 -3
- package/commands/work-on/build/context.md +36 -5
- package/commands/work-on/build/validate.md +16 -7
- package/commands/work-on/close.md +129 -1
- package/commands/work-on/investigate.md +24 -1
- package/commands/work-on.md +226 -8
- package/docs/site/annotations-explained.md +55 -0
- package/docs/site/command-learning-path.md +104 -0
- package/docs/site/command-reference.md +3 -0
- package/docs/site/getting-started.md +36 -14
- package/docs/site/troubleshooting.md +208 -0
- package/docs/spec/forge-protocol-v1.md +768 -0
- package/examples/forgedock-demo/README.md +113 -0
- package/examples/forgedock-demo/bootstrap.sh +125 -0
- package/examples/forgedock-demo/issues/01-bug-delete-missing-auth.md +37 -0
- package/examples/forgedock-demo/issues/02-feature-filter-notes.md +37 -0
- package/examples/forgedock-demo/issues/03-refactor-router-table.md +33 -0
- package/examples/forgedock-demo/issues/04-perf-index-lookup.md +35 -0
- package/examples/forgedock-demo/issues/05-docs-api-reference.md +39 -0
- package/examples/forgedock-demo/labels.json +21 -0
- package/examples/forgedock-demo/package.json +16 -0
- package/examples/forgedock-demo/scripts/smoke.js +61 -0
- package/examples/forgedock-demo/src/auth.js +28 -0
- package/examples/forgedock-demo/src/db.js +66 -0
- package/examples/forgedock-demo/src/routes/notes.js +64 -0
- package/examples/forgedock-demo/src/server.js +79 -0
- package/package.json +5 -1
- package/templates/forge.yaml.minimal +44 -0
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
# FORGE Annotation Protocol
|
|
2
|
+
|
|
3
|
+
**Version**: 1.0
|
|
4
|
+
**Status**: Published
|
|
5
|
+
**License**: [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/)
|
|
6
|
+
|
|
7
|
+
> This specification is licensed under the Creative Commons Attribution 4.0
|
|
8
|
+
> International License (CC-BY-4.0). You are free to share and adapt it,
|
|
9
|
+
> including in commercial products, provided you give appropriate credit.
|
|
10
|
+
> The license applies to **this specification document only** — it does not
|
|
11
|
+
> govern any particular software implementation of the protocol.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Introduction
|
|
16
|
+
|
|
17
|
+
The FORGE Annotation Protocol is an open, machine-readable convention for AI
|
|
18
|
+
development agents to pass structured context to one another through the
|
|
19
|
+
artifacts of a code-hosting platform — issues and pull requests.
|
|
20
|
+
|
|
21
|
+
Modern AI coding agents are stateless. When a session ends, the next agent
|
|
22
|
+
starts with no memory of what previous agents investigated, decided, or built.
|
|
23
|
+
Teams that chain agents together (an investigator, then a builder, then a
|
|
24
|
+
reviewer) need a durable place to record each agent's output so the next agent
|
|
25
|
+
can resume without re-deriving everything.
|
|
26
|
+
|
|
27
|
+
FORGE solves this by defining a small set of **annotations**: structured blocks
|
|
28
|
+
of text, wrapped in HTML comment tags, posted as ordinary issue or pull-request
|
|
29
|
+
comments. Each agent writes the annotations for the work it completes; each
|
|
30
|
+
downstream agent reads the annotations that came before. Because the host
|
|
31
|
+
platform stores comments permanently and exposes them through a standard API,
|
|
32
|
+
the context survives session restarts, context-window compaction, and tooling
|
|
33
|
+
changes.
|
|
34
|
+
|
|
35
|
+
This document specifies version 1.0 of the protocol. It is self-contained: a
|
|
36
|
+
conforming producer or consumer can be built from this document alone, with no
|
|
37
|
+
dependency on any specific agent framework, language model, editor, or vendor.
|
|
38
|
+
|
|
39
|
+
### 1.1 Goals
|
|
40
|
+
|
|
41
|
+
- **Interoperability** — any agent that can read and write platform comments can
|
|
42
|
+
participate, regardless of which language model or tool drives it.
|
|
43
|
+
- **Durability** — context is stored in append-only platform artifacts, not in
|
|
44
|
+
conversation history or ephemeral memory.
|
|
45
|
+
- **Queryability** — annotations can be located with simple text-contains
|
|
46
|
+
filters over comment bodies; no database or semantic index is required.
|
|
47
|
+
- **Human-readability** — annotations are Markdown that a person can read
|
|
48
|
+
directly in the issue thread.
|
|
49
|
+
|
|
50
|
+
### 1.2 Terminology
|
|
51
|
+
|
|
52
|
+
The key words **MUST**, **MUST NOT**, **SHOULD**, **SHOULD NOT**, and **MAY**
|
|
53
|
+
in this document are to be interpreted as described in RFC 2119.
|
|
54
|
+
|
|
55
|
+
- **Annotation** — a structured block of text identified by a FORGE tag.
|
|
56
|
+
- **Producer** — an agent (or any process) that writes annotations.
|
|
57
|
+
- **Consumer** — an agent, automation, or human that reads annotations.
|
|
58
|
+
- **Host platform** — the code-hosting service whose issue/PR comments transport
|
|
59
|
+
annotations (e.g., a Git hosting service exposing a comments API).
|
|
60
|
+
- **Completion sentinel** — a tag that marks an annotation as fully written.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 2. Transport and Encoding
|
|
65
|
+
|
|
66
|
+
| Property | Definition |
|
|
67
|
+
|----------|------------|
|
|
68
|
+
| Transport | The host platform's issue/PR comment API |
|
|
69
|
+
| Container | One annotation lives inside one platform comment; a comment MAY contain more than one annotation |
|
|
70
|
+
| Encoding | An opening HTML comment tag followed by a Markdown body |
|
|
71
|
+
| Persistence | Comments are append-only and permanent; annotations survive restarts and compaction |
|
|
72
|
+
| Query interface | Text-contains filtering on comment bodies (e.g., `body` contains `FORGE:INVESTIGATOR`) |
|
|
73
|
+
|
|
74
|
+
HTML comment tags are chosen because they render invisibly in Markdown views,
|
|
75
|
+
so annotations do not clutter the human reading experience, yet remain trivially
|
|
76
|
+
machine-parseable.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 3. Syntax
|
|
81
|
+
|
|
82
|
+
### 3.1 Opening tag
|
|
83
|
+
|
|
84
|
+
Every annotation begins with an opening tag on its own line:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
<!-- FORGE:{TYPE} -->
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`{TYPE}` is an uppercase identifier naming the annotation type (see Section 4).
|
|
91
|
+
The Markdown body of the annotation follows on subsequent lines.
|
|
92
|
+
|
|
93
|
+
An annotation ends at the next `<!-- FORGE:` tag within the same comment, or at
|
|
94
|
+
the end of the comment body, whichever comes first.
|
|
95
|
+
|
|
96
|
+
### 3.2 Completion sentinels
|
|
97
|
+
|
|
98
|
+
A producer signals that an annotation is fully written by emitting a completion
|
|
99
|
+
sentinel as the final line of the annotation:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
<!-- {TYPE}:COMPLETE -->
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Some annotation types use a domain-specific sentinel rather than the type name;
|
|
106
|
+
each type in Section 4 states its sentinel explicitly. A consumer **MUST NOT**
|
|
107
|
+
treat an annotation as complete unless its completion sentinel is present.
|
|
108
|
+
|
|
109
|
+
### 3.3 Partial sentinels
|
|
110
|
+
|
|
111
|
+
When a producer is interrupted (session ends, error, time budget exceeded) after
|
|
112
|
+
beginning an annotation but before finishing it, the producer **MAY** mark the
|
|
113
|
+
annotation partial:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
<!-- {TYPE}:PARTIAL -->
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
An annotation that has neither a completion nor a partial sentinel is treated as
|
|
120
|
+
interrupted. A consumer **SHOULD** delete an interrupted or partial annotation
|
|
121
|
+
and request that the producing phase be re-run, so that downstream consumers
|
|
122
|
+
never read incomplete context.
|
|
123
|
+
|
|
124
|
+
### 3.4 Inline value form
|
|
125
|
+
|
|
126
|
+
Some annotations carry a single value (such as a URL) directly in the tag rather
|
|
127
|
+
than in a Markdown body:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
<!-- FORGE:{TYPE}: {value} -->
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The value is everything between the colon-space after `{TYPE}` and the closing
|
|
134
|
+
` -->`. Consumers extract it with a simple capture over that span.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 4. Annotation Types
|
|
139
|
+
|
|
140
|
+
This section defines the annotation types reserved by version 1.0. Producers
|
|
141
|
+
**MAY** emit any subset relevant to their workflow; a minimal pipeline can use
|
|
142
|
+
as few as two types (for example, an investigator annotation and a builder
|
|
143
|
+
annotation).
|
|
144
|
+
|
|
145
|
+
### 4.1 Lifecycle annotations
|
|
146
|
+
|
|
147
|
+
Lifecycle annotations are posted as issue comments and form the primary context
|
|
148
|
+
chain for working an issue from triage to completion.
|
|
149
|
+
|
|
150
|
+
#### `FORGE:INVESTIGATOR`
|
|
151
|
+
|
|
152
|
+
- **Written by**: an investigation agent
|
|
153
|
+
- **Read by**: builder, architect, and decomposition agents
|
|
154
|
+
- **Completion sentinel**: `<!-- INVESTIGATION:COMPLETE -->`
|
|
155
|
+
|
|
156
|
+
Records the outcome of determining whether an issue is valid, its root cause,
|
|
157
|
+
and what should be done.
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
<!-- FORGE:INVESTIGATOR -->
|
|
161
|
+
## Investigation Report
|
|
162
|
+
|
|
163
|
+
**Verdict**: {CONFIRMED|PARTIAL|INVALID}
|
|
164
|
+
**Confidence**: {HIGH|MEDIUM|LOW}
|
|
165
|
+
**Severity**: {CRITICAL|HIGH|MEDIUM|LOW}
|
|
166
|
+
**Task Type**: {Bug Fix|Feature|Refactor|Maintenance|Investigation}
|
|
167
|
+
|
|
168
|
+
### What Was Claimed
|
|
169
|
+
{summary of what the issue describes}
|
|
170
|
+
|
|
171
|
+
### What We Found
|
|
172
|
+
{what the code actually shows — specific evidence}
|
|
173
|
+
|
|
174
|
+
### Root Cause
|
|
175
|
+
{specific root cause, with file:line references where applicable}
|
|
176
|
+
|
|
177
|
+
### Affected Files
|
|
178
|
+
{numbered list of files that need changes}
|
|
179
|
+
|
|
180
|
+
### Evidence
|
|
181
|
+
{specific findings — function names, line numbers, observed behavior}
|
|
182
|
+
|
|
183
|
+
### Recommendation
|
|
184
|
+
{what to build or fix, concrete and actionable}
|
|
185
|
+
|
|
186
|
+
### Decomposition Assessment
|
|
187
|
+
**{YES|NO}** — {reason}
|
|
188
|
+
|
|
189
|
+
<!-- INVESTIGATION:COMPLETE -->
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
| Field | Values | Required |
|
|
193
|
+
|-------|--------|----------|
|
|
194
|
+
| Verdict | `CONFIRMED` / `PARTIAL` / `INVALID` | Yes |
|
|
195
|
+
| Confidence | `HIGH` / `MEDIUM` / `LOW` | Yes |
|
|
196
|
+
| Severity | `CRITICAL` / `HIGH` / `MEDIUM` / `LOW` | Yes |
|
|
197
|
+
| Task Type | one of the listed task types | Yes |
|
|
198
|
+
| Decomposition Assessment | `YES` or `NO` with a reason | Yes |
|
|
199
|
+
|
|
200
|
+
A consumer routes on the verdict: `CONFIRMED`/`PARTIAL` proceeds to build (or to
|
|
201
|
+
decomposition if the assessment is `YES`); `INVALID` closes the issue.
|
|
202
|
+
|
|
203
|
+
#### `FORGE:DECOMPOSED`
|
|
204
|
+
|
|
205
|
+
- **Written by**: a decomposition agent
|
|
206
|
+
- **Read by**: orchestration agents and the parent-issue tracker
|
|
207
|
+
- **Completion sentinel**: `<!-- FORGE:DECOMPOSED:COMPLETE -->`
|
|
208
|
+
|
|
209
|
+
Posted on a parent issue after it has been split into sub-issues, each of which
|
|
210
|
+
runs its own pipeline.
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
<!-- FORGE:DECOMPOSED -->
|
|
214
|
+
## Decomposition Complete
|
|
215
|
+
|
|
216
|
+
### Sub-Issues Created
|
|
217
|
+
- #{NUMBER}: {TITLE}
|
|
218
|
+
|
|
219
|
+
### Decomposition Rationale
|
|
220
|
+
{why decomposition was needed}
|
|
221
|
+
|
|
222
|
+
<!-- FORGE:DECOMPOSED:COMPLETE -->
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### `FORGE:CONTRACT`
|
|
226
|
+
|
|
227
|
+
- **Written by**: a builder agent, before writing code
|
|
228
|
+
- **Read by**: the builder (implementation step) and review agents
|
|
229
|
+
|
|
230
|
+
Defines the scope of a build task — a binding agreement between investigation
|
|
231
|
+
findings and what will actually be built.
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
<!-- FORGE:CONTRACT -->
|
|
235
|
+
## Builder Contract
|
|
236
|
+
|
|
237
|
+
**Task type**: {TASK_TYPE}
|
|
238
|
+
|
|
239
|
+
### Proposed Approach
|
|
240
|
+
{brief description of the implementation approach}
|
|
241
|
+
|
|
242
|
+
### Deliverables
|
|
243
|
+
| File | Change | Why |
|
|
244
|
+
|------|--------|-----|
|
|
245
|
+
| {filepath} | {what changes} | {why this change is needed} |
|
|
246
|
+
|
|
247
|
+
### Acceptance Criteria
|
|
248
|
+
- [ ] {specific, testable criterion}
|
|
249
|
+
|
|
250
|
+
### Quality Considerations
|
|
251
|
+
{auth model, new configuration, data-safety, security surface, migration risk}
|
|
252
|
+
|
|
253
|
+
### Out of Scope
|
|
254
|
+
{items explicitly excluded}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### `FORGE:CONTEXT`
|
|
258
|
+
|
|
259
|
+
- **Written by**: a context-gathering agent
|
|
260
|
+
- **Read by**: the builder (before touching code)
|
|
261
|
+
- **Completion sentinels**: `<!-- FORGE:CONTEXT:COMPLETE -->` (full),
|
|
262
|
+
`<!-- FORGE:CONTEXT:PARTIAL -->` (time-limited)
|
|
263
|
+
|
|
264
|
+
Surfaces institutional memory before implementation: past review findings,
|
|
265
|
+
historical bugs, related code paths, and proven patterns.
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
<!-- FORGE:CONTEXT -->
|
|
269
|
+
## Implementation Context for #{NUMBER}
|
|
270
|
+
|
|
271
|
+
### Known Pitfalls for This Area
|
|
272
|
+
{prevention rules from past findings on these files}
|
|
273
|
+
|
|
274
|
+
### Historical Findings on These Files
|
|
275
|
+
{past findings, with pattern and prevention details}
|
|
276
|
+
|
|
277
|
+
### Past Bugs in This Module
|
|
278
|
+
{closed bug issues found via history mining}
|
|
279
|
+
|
|
280
|
+
### Related Code Paths (must stay consistent)
|
|
281
|
+
{files that import or call the functions being changed}
|
|
282
|
+
|
|
283
|
+
### Patterns That Cause Bugs Here
|
|
284
|
+
{recurring bug types synthesized from history}
|
|
285
|
+
|
|
286
|
+
### Successful Similar Implementations
|
|
287
|
+
{positive patterns from prior merged changes}
|
|
288
|
+
|
|
289
|
+
<!-- FORGE:CONTEXT:COMPLETE -->
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
#### `FORGE:ARCHITECT`
|
|
293
|
+
|
|
294
|
+
- **Written by**: an architecture agent
|
|
295
|
+
- **Read by**: the builder (primary implementation guide)
|
|
296
|
+
- **Completion sentinels**: `<!-- FORGE:ARCHITECT:COMPLETE -->` (full),
|
|
297
|
+
`<!-- FORGE:ARCHITECT:PARTIAL -->` (time-limited)
|
|
298
|
+
|
|
299
|
+
Contains an ordered implementation plan tracing all affected code paths,
|
|
300
|
+
consistency rules, sequencing, and risks. When present, a builder follows it.
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
<!-- FORGE:ARCHITECT -->
|
|
304
|
+
## Implementation Plan for #{NUMBER}
|
|
305
|
+
|
|
306
|
+
### Affected Paths (ALL must be updated)
|
|
307
|
+
| # | File | Function/Class | Change Required | Why |
|
|
308
|
+
|---|------|----------------|-----------------|-----|
|
|
309
|
+
| 1 | {filepath} | {function or class} | {what to change} | {reason} |
|
|
310
|
+
|
|
311
|
+
### Implementation Order
|
|
312
|
+
1. {first change} — {why first}
|
|
313
|
+
|
|
314
|
+
### Consistency Checks
|
|
315
|
+
- [ ] {invariant all paths must satisfy}
|
|
316
|
+
|
|
317
|
+
### Risk Assessment
|
|
318
|
+
| Risk | Severity | Mitigation |
|
|
319
|
+
|------|----------|------------|
|
|
320
|
+
| {risk} | HIGH/MEDIUM/LOW | {mitigation} |
|
|
321
|
+
|
|
322
|
+
### Files to Read Before Coding
|
|
323
|
+
- `{filepath}` — {why to read it}
|
|
324
|
+
|
|
325
|
+
<!-- FORGE:ARCHITECT:COMPLETE -->
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
#### `FORGE:BUILDER`
|
|
329
|
+
|
|
330
|
+
- **Written by**: an implementation agent, after committing work
|
|
331
|
+
- **Read by**: review agents and the close phase
|
|
332
|
+
- **Completion sentinel**: `<!-- FORGE:BUILDER:COMPLETE -->`
|
|
333
|
+
|
|
334
|
+
The primary handoff annotation to review. Captures branch, commits, files
|
|
335
|
+
changed, and a testing checklist.
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
<!-- FORGE:BUILDER -->
|
|
339
|
+
## Implementation Complete
|
|
340
|
+
|
|
341
|
+
**Branch**: `{branch-name}`
|
|
342
|
+
**Commits**: {commit SHA(s)}
|
|
343
|
+
**Files changed**: {count}
|
|
344
|
+
|
|
345
|
+
### Approach
|
|
346
|
+
{what was built, key decisions}
|
|
347
|
+
|
|
348
|
+
### Changes
|
|
349
|
+
- `{filepath}` — {what changed}
|
|
350
|
+
|
|
351
|
+
### Acceptance Criteria Status
|
|
352
|
+
- [x] {criterion} — PASS
|
|
353
|
+
- [ ] {criterion} — FAIL (reason)
|
|
354
|
+
|
|
355
|
+
### Testing Checklist
|
|
356
|
+
- [ ] {test scenario}
|
|
357
|
+
|
|
358
|
+
<!-- FORGE:BUILDER:COMPLETE -->
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
#### `FORGE:REVIEWER`
|
|
362
|
+
|
|
363
|
+
- **Written by**: domain review agents, on the pull request
|
|
364
|
+
- **Read by**: the review orchestrator (determines merge eligibility) and
|
|
365
|
+
future context agents
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
<!-- FORGE:REVIEWER -->
|
|
369
|
+
## Review — {AGENT_TYPE}
|
|
370
|
+
|
|
371
|
+
**Verdict**: {APPROVED|CHANGES_REQUESTED|COMMENTED}
|
|
372
|
+
|
|
373
|
+
### Findings
|
|
374
|
+
- **Severity**: {CRITICAL|HIGH|MEDIUM|LOW}
|
|
375
|
+
**Location**: `{filepath}:{line}`
|
|
376
|
+
**Issue**: {description}
|
|
377
|
+
**Suggested fix**: {fix}
|
|
378
|
+
**Prevention**: {rule that would prevent recurrence}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
`{AGENT_TYPE}` names the review domain (for example `SECURITY`, `LOGIC`,
|
|
382
|
+
`FRONTEND`, `DATABASE`).
|
|
383
|
+
|
|
384
|
+
#### `FORGE:TRAJECTORY`
|
|
385
|
+
|
|
386
|
+
- **Written by**: the orchestrator, once per issue lifecycle
|
|
387
|
+
- **Read by**: reporting/automation consumers and future context agents
|
|
388
|
+
|
|
389
|
+
A permanent audit trail of a completed pipeline run.
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
<!-- FORGE:TRAJECTORY -->
|
|
393
|
+
## Pipeline Trajectory — #{NUMBER}
|
|
394
|
+
|
|
395
|
+
| Phase | Result | Notes |
|
|
396
|
+
|-------|--------|-------|
|
|
397
|
+
| Context Load | done | {lane} → `{base-branch}` |
|
|
398
|
+
| Investigation | {VERDICT} ({CONFIDENCE}) | Task type: {TASK_TYPE} |
|
|
399
|
+
| Decomposition | skipped | {reason} |
|
|
400
|
+
| Build | done | Branch: `{branch}` |
|
|
401
|
+
| Quality Gate | passed | {N} iterations |
|
|
402
|
+
| Review + Merge | merged | PR #{PR_NUMBER} → `{base-branch}` |
|
|
403
|
+
| Close | done | Issue closed |
|
|
404
|
+
|
|
405
|
+
**Decisions**: {key decisions}
|
|
406
|
+
**Anomalies**: {anomalies or None}
|
|
407
|
+
**Completed**: {ISO 8601 timestamp}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### 4.2 Cross-artifact annotations
|
|
411
|
+
|
|
412
|
+
These annotations move context between issues — useful when a parent issue is
|
|
413
|
+
decomposed into sub-issues, or when many issues share a milestone.
|
|
414
|
+
|
|
415
|
+
#### `FORGE:KNOWLEDGE_GIST`
|
|
416
|
+
|
|
417
|
+
- **Form**: inline value (Section 3.4)
|
|
418
|
+
- **Location**: issue comment
|
|
419
|
+
|
|
420
|
+
Points to an external, linkable artifact (such as a hosted snippet) holding the
|
|
421
|
+
full investigation findings, so downstream issues can fetch prior context.
|
|
422
|
+
|
|
423
|
+
```
|
|
424
|
+
<!-- FORGE:KNOWLEDGE_GIST: {https://example.com/artifact} -->
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
#### `FORGE:MILESTONE_INDEX`
|
|
428
|
+
|
|
429
|
+
- **Form**: inline value
|
|
430
|
+
- **Location**: the milestone description field
|
|
431
|
+
|
|
432
|
+
Points to an index artifact aggregating the `FORGE:KNOWLEDGE_GIST` links for a
|
|
433
|
+
milestone, giving any agent working any milestone issue one-fetch access to all
|
|
434
|
+
prior investigations.
|
|
435
|
+
|
|
436
|
+
```
|
|
437
|
+
<!-- FORGE:MILESTONE_INDEX: {https://example.com/index} -->
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
#### `FORGE:PRIOR_GIST`
|
|
441
|
+
|
|
442
|
+
- **Form**: inline value
|
|
443
|
+
- **Location**: a sub-issue body
|
|
444
|
+
|
|
445
|
+
Embedded by a decomposition agent; points to the parent issue's knowledge
|
|
446
|
+
artifact so a sub-issue builder can fetch upstream context directly.
|
|
447
|
+
|
|
448
|
+
```
|
|
449
|
+
<!-- FORGE:PRIOR_GIST: {https://example.com/artifact} -->
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### 4.3 Control and error markers
|
|
453
|
+
|
|
454
|
+
These markers carry no Markdown body; their presence is the signal.
|
|
455
|
+
|
|
456
|
+
| Marker | Meaning |
|
|
457
|
+
|--------|---------|
|
|
458
|
+
| `<!-- FORGE:REVIEW_STARTED -->` | The review phase has been invoked for this issue |
|
|
459
|
+
| `<!-- FORGE:ANCESTRY_FAILED -->` | A branch ancestry check failed (unexpected merge commits) |
|
|
460
|
+
| `<!-- FORGE:GATE_FAILED -->` | A quality gate failed after its retry budget |
|
|
461
|
+
| `<!-- FORGE:PUSH_BLOCKED -->` | A branch push was blocked by platform policy |
|
|
462
|
+
| `<!-- FORGE:PUSH_FAILED -->` | A branch push failed after retry |
|
|
463
|
+
|
|
464
|
+
Error markers signal that automated processing stopped and human attention is
|
|
465
|
+
needed.
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## 5. The Context Chain
|
|
470
|
+
|
|
471
|
+
Lifecycle annotations form an ordered chain. Each stage reads the outputs of all
|
|
472
|
+
preceding stages, so context accumulates on the issue rather than in any agent's
|
|
473
|
+
memory:
|
|
474
|
+
|
|
475
|
+
```
|
|
476
|
+
Issue body
|
|
477
|
+
↓
|
|
478
|
+
FORGE:INVESTIGATOR
|
|
479
|
+
↓
|
|
480
|
+
FORGE:DECOMPOSED (only if the issue is decomposed)
|
|
481
|
+
↓
|
|
482
|
+
FORGE:CONTRACT
|
|
483
|
+
↓
|
|
484
|
+
FORGE:CONTEXT
|
|
485
|
+
↓
|
|
486
|
+
FORGE:ARCHITECT
|
|
487
|
+
↓
|
|
488
|
+
FORGE:BUILDER
|
|
489
|
+
↓
|
|
490
|
+
FORGE:REVIEWER (on the pull request)
|
|
491
|
+
↓
|
|
492
|
+
FORGE:TRAJECTORY
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Cross-artifact context for decomposed or milestone workflows:
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
Parent issue: FORGE:INVESTIGATOR → FORGE:KNOWLEDGE_GIST (artifact link)
|
|
499
|
+
↓
|
|
500
|
+
Milestone description: FORGE:MILESTONE_INDEX (index link)
|
|
501
|
+
↓
|
|
502
|
+
Sub-issue body: FORGE:PRIOR_GIST (link from the parent's artifact)
|
|
503
|
+
↓
|
|
504
|
+
Sub-issue: FORGE:CONTEXT reads FORGE:PRIOR_GIST to fetch upstream context
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## 6. Label State Machine
|
|
510
|
+
|
|
511
|
+
Annotations record *what happened*; labels record *where a unit of work is* so a
|
|
512
|
+
consumer can determine the current stage without reading every comment. The
|
|
513
|
+
protocol reserves the `workflow:` label namespace:
|
|
514
|
+
|
|
515
|
+
| Label | Meaning |
|
|
516
|
+
|-------|---------|
|
|
517
|
+
| `workflow:investigating` | Investigation in progress |
|
|
518
|
+
| `workflow:ready-to-build` | Investigation complete, build not started |
|
|
519
|
+
| `workflow:building` | Build in progress |
|
|
520
|
+
| `workflow:in-review` | Pull request open, review active |
|
|
521
|
+
| `workflow:merged` | Pull request merged, work item closed |
|
|
522
|
+
| `workflow:invalid` | Closed as invalid |
|
|
523
|
+
| `workflow:decomposed` | Split into sub-issues |
|
|
524
|
+
| `needs-human` | Blocked; human intervention required |
|
|
525
|
+
|
|
526
|
+
**Terminal labels** (processing stops when any is set): `workflow:merged`,
|
|
527
|
+
`workflow:invalid`, `workflow:decomposed`, `needs-human`.
|
|
528
|
+
|
|
529
|
+
Labels and annotations are complementary: labels give a fast state lookup,
|
|
530
|
+
annotations give the full context behind that state.
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## 7. Conformance
|
|
535
|
+
|
|
536
|
+
### 7.1 Conforming producer
|
|
537
|
+
|
|
538
|
+
A conforming producer:
|
|
539
|
+
|
|
540
|
+
1. Writes annotations using the exact opening tag `<!-- FORGE:{TYPE} -->`.
|
|
541
|
+
2. Emits the correct completion sentinel as the final line of each annotation it
|
|
542
|
+
finishes.
|
|
543
|
+
3. Marks interrupted annotations with the partial sentinel where it can.
|
|
544
|
+
4. Writes state to the host platform after each significant step, so progress
|
|
545
|
+
survives interruption.
|
|
546
|
+
|
|
547
|
+
### 7.2 Conforming consumer
|
|
548
|
+
|
|
549
|
+
A conforming consumer:
|
|
550
|
+
|
|
551
|
+
1. Locates annotations by text-contains filtering on comment bodies for
|
|
552
|
+
`FORGE:{TYPE}`.
|
|
553
|
+
2. Treats an annotation as complete only when its completion sentinel is present.
|
|
554
|
+
3. Re-reads platform state at the start of each stage rather than relying on
|
|
555
|
+
in-memory context.
|
|
556
|
+
4. Tolerates unknown annotation types gracefully — it skips types it does not
|
|
557
|
+
recognize and **MUST NOT** fail on them. This is what makes the extension
|
|
558
|
+
mechanism (Section 8) safe.
|
|
559
|
+
5. Honors terminal labels (Section 6) — it stops processing a work item in a
|
|
560
|
+
terminal state.
|
|
561
|
+
|
|
562
|
+
### 7.3 Conformance checks
|
|
563
|
+
|
|
564
|
+
A producer's output for a completed work item can be verified by confirming the
|
|
565
|
+
expected annotations are present and complete. The following examples use a
|
|
566
|
+
generic `gh`-style comments query; substitute your platform's equivalent.
|
|
567
|
+
|
|
568
|
+
Annotation presence:
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
OWNER="your-org"; REPO="your-repo"; NUMBER=42
|
|
572
|
+
REQUIRED=("FORGE:INVESTIGATOR" "FORGE:CONTRACT" "FORGE:CONTEXT" \
|
|
573
|
+
"FORGE:ARCHITECT" "FORGE:BUILDER" "FORGE:TRAJECTORY")
|
|
574
|
+
for a in "${REQUIRED[@]}"; do
|
|
575
|
+
COUNT=$(gh api repos/$OWNER/$REPO/issues/$NUMBER/comments \
|
|
576
|
+
--jq "[.[] | select(.body | contains(\"$a\"))] | length")
|
|
577
|
+
[ "$COUNT" -gt 0 ] && echo "ok $a ($COUNT)" || echo "MISS $a"
|
|
578
|
+
done
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Completion sentinel:
|
|
582
|
+
|
|
583
|
+
```bash
|
|
584
|
+
BODY=$(gh api repos/$OWNER/$REPO/issues/$NUMBER/comments \
|
|
585
|
+
--jq '.[] | select(.body | contains("FORGE:INVESTIGATOR")) | .body' | head -1)
|
|
586
|
+
echo "$BODY" | grep -q "INVESTIGATION:COMPLETE" \
|
|
587
|
+
&& echo "investigator complete" || echo "investigator INCOMPLETE"
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Terminal label:
|
|
591
|
+
|
|
592
|
+
```bash
|
|
593
|
+
gh issue view $NUMBER -R $OWNER/$REPO --json labels \
|
|
594
|
+
--jq '[.labels[].name | select(startswith("workflow:"))]'
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
---
|
|
598
|
+
|
|
599
|
+
## 8. Extension Mechanism
|
|
600
|
+
|
|
601
|
+
The protocol is intentionally minimal. A producer **MAY** define new annotation
|
|
602
|
+
types by following the naming convention:
|
|
603
|
+
|
|
604
|
+
```
|
|
605
|
+
<!-- FORGE:YOUR_CUSTOM_TYPE -->
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
To avoid collisions, custom types **SHOULD** use a name that is unlikely to
|
|
609
|
+
clash with reserved types — for example, a vendor or project prefix
|
|
610
|
+
(`FORGE:ACME_SECURITY_SCAN`). Because every conforming consumer ignores types it
|
|
611
|
+
does not recognize (Section 7.2), custom annotations are safe to add: they are
|
|
612
|
+
visible to producers and consumers that understand them and invisible to those
|
|
613
|
+
that do not.
|
|
614
|
+
|
|
615
|
+
New **reserved** types and new optional fields are added in backward-compatible
|
|
616
|
+
minor revisions; renaming or removing a reserved type, or removing a required
|
|
617
|
+
field, is a major-version change (Section 10).
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## 9. Worked Example: Producer and Consumer
|
|
622
|
+
|
|
623
|
+
This example shows a conforming producer recording context on an issue, and a
|
|
624
|
+
conforming consumer — a continuous-integration job — reading that context.
|
|
625
|
+
|
|
626
|
+
### 9.1 Conforming producer
|
|
627
|
+
|
|
628
|
+
An investigation agent finishes triaging issue #128 and posts:
|
|
629
|
+
|
|
630
|
+
```
|
|
631
|
+
<!-- FORGE:INVESTIGATOR -->
|
|
632
|
+
## Investigation Report
|
|
633
|
+
|
|
634
|
+
**Verdict**: CONFIRMED
|
|
635
|
+
**Confidence**: HIGH
|
|
636
|
+
**Severity**: HIGH
|
|
637
|
+
**Task Type**: Bug Fix
|
|
638
|
+
|
|
639
|
+
### Root Cause
|
|
640
|
+
`payments/validator.py:142` — the billing-profile lookup does not guard
|
|
641
|
+
against a null profile for free-tier users, raising on every checkout.
|
|
642
|
+
|
|
643
|
+
### Affected Files
|
|
644
|
+
1. `payments/validator.py`
|
|
645
|
+
|
|
646
|
+
### Recommendation
|
|
647
|
+
Return an empty profile when the lookup is null; add a regression test.
|
|
648
|
+
|
|
649
|
+
### Decomposition Assessment
|
|
650
|
+
**NO** — single-file fix.
|
|
651
|
+
|
|
652
|
+
<!-- INVESTIGATION:COMPLETE -->
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
After implementing and merging the fix, the builder and orchestrator post the
|
|
656
|
+
handoff and trajectory annotations:
|
|
657
|
+
|
|
658
|
+
```
|
|
659
|
+
<!-- FORGE:BUILDER -->
|
|
660
|
+
## Implementation Complete
|
|
661
|
+
|
|
662
|
+
**Branch**: `fix/null-billing-profile-128`
|
|
663
|
+
**Commits**: a1b2c3d
|
|
664
|
+
**Files changed**: 2
|
|
665
|
+
|
|
666
|
+
### Changes
|
|
667
|
+
- `payments/validator.py` — guard null profile, return empty profile
|
|
668
|
+
- `tests/test_validator.py` — add free-tier regression test
|
|
669
|
+
|
|
670
|
+
<!-- FORGE:BUILDER:COMPLETE -->
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
```
|
|
674
|
+
<!-- FORGE:TRAJECTORY -->
|
|
675
|
+
## Pipeline Trajectory — #128
|
|
676
|
+
|
|
677
|
+
| Phase | Result | Notes |
|
|
678
|
+
|-------|--------|-------|
|
|
679
|
+
| Investigation | CONFIRMED (HIGH) | Task type: Bug Fix |
|
|
680
|
+
| Build | done | Branch: `fix/null-billing-profile-128` |
|
|
681
|
+
| Review + Merge | merged | PR #131 |
|
|
682
|
+
| Close | done | Issue closed |
|
|
683
|
+
|
|
684
|
+
**Decisions**: Guard at the lookup site rather than each caller.
|
|
685
|
+
**Anomalies**: None
|
|
686
|
+
**Completed**: 2026-01-15T09:30:00Z
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### 9.2 Conforming consumer
|
|
690
|
+
|
|
691
|
+
A continuous-integration job consumes `FORGE:TRAJECTORY` to publish a release
|
|
692
|
+
note whenever an issue is closed. This consumer is fully generic: it depends
|
|
693
|
+
only on the protocol, not on the agent that produced the annotations. The
|
|
694
|
+
example uses GitHub Actions, but any automation platform with API access works
|
|
695
|
+
identically.
|
|
696
|
+
|
|
697
|
+
```yaml
|
|
698
|
+
# .github/workflows/forge-trajectory-report.yml
|
|
699
|
+
name: FORGE Trajectory Report
|
|
700
|
+
|
|
701
|
+
on:
|
|
702
|
+
issues:
|
|
703
|
+
types: [closed]
|
|
704
|
+
|
|
705
|
+
permissions:
|
|
706
|
+
issues: read
|
|
707
|
+
|
|
708
|
+
jobs:
|
|
709
|
+
report:
|
|
710
|
+
runs-on: ubuntu-latest
|
|
711
|
+
steps:
|
|
712
|
+
- name: Extract and print the FORGE:TRAJECTORY annotation
|
|
713
|
+
env:
|
|
714
|
+
GH_TOKEN: ${{ github.token }}
|
|
715
|
+
REPO: ${{ github.repository }}
|
|
716
|
+
NUMBER: ${{ github.event.issue.number }}
|
|
717
|
+
run: |
|
|
718
|
+
# A conforming consumer locates an annotation by text-contains
|
|
719
|
+
# filtering on comment bodies, then checks for its presence.
|
|
720
|
+
TRAJECTORY=$(gh api "repos/$REPO/issues/$NUMBER/comments" \
|
|
721
|
+
--jq '.[] | select(.body | contains("FORGE:TRAJECTORY")) | .body' \
|
|
722
|
+
| head -1)
|
|
723
|
+
|
|
724
|
+
if [ -z "$TRAJECTORY" ]; then
|
|
725
|
+
echo "No FORGE:TRAJECTORY annotation found — skipping (tolerant)."
|
|
726
|
+
exit 0
|
|
727
|
+
fi
|
|
728
|
+
|
|
729
|
+
echo "Found trajectory for issue #$NUMBER:"
|
|
730
|
+
echo "$TRAJECTORY"
|
|
731
|
+
# A real consumer would forward this to a changelog, dashboard,
|
|
732
|
+
# or release-notes pipeline.
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
The job is tolerant by design (Section 7.2): if an issue carries no
|
|
736
|
+
`FORGE:TRAJECTORY` annotation, it exits cleanly rather than failing. Any
|
|
737
|
+
producer that emits a conforming `FORGE:TRAJECTORY` annotation — regardless of
|
|
738
|
+
which tool or model produced it — interoperates with this consumer unchanged.
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## 10. Versioning
|
|
743
|
+
|
|
744
|
+
This document specifies **version 1.0**.
|
|
745
|
+
|
|
746
|
+
- **Minor** revisions add backward-compatible changes: new reserved annotation
|
|
747
|
+
types, new optional fields. Conforming consumers continue to work because they
|
|
748
|
+
ignore unknown types and fields (Section 7.2).
|
|
749
|
+
- **Major** revisions introduce breaking changes: renamed or removed reserved
|
|
750
|
+
types, or removed required fields.
|
|
751
|
+
|
|
752
|
+
Annotations do not carry an explicit version field. Conforming consumers
|
|
753
|
+
**MUST** tolerate unknown annotation types gracefully.
|
|
754
|
+
|
|
755
|
+
---
|
|
756
|
+
|
|
757
|
+
## 11. Acknowledgements
|
|
758
|
+
|
|
759
|
+
The FORGE Annotation Protocol was first developed and proven in a production
|
|
760
|
+
autonomous-development pipeline, where it coordinated investigator, builder,
|
|
761
|
+
and reviewer agents across tens of thousands of issues. This specification
|
|
762
|
+
generalizes that wire format into a tool-neutral, openly licensed standard so
|
|
763
|
+
that any agent pipeline can adopt and interoperate with it.
|
|
764
|
+
|
|
765
|
+
---
|
|
766
|
+
|
|
767
|
+
*FORGE Annotation Protocol v1.0 — released under
|
|
768
|
+
[CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/).*
|