forgedock 1.1.1 → 1.1.3
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 +53 -8
- package/bin/batch-runner.mjs +339 -0
- package/bin/demo.mjs +92 -7
- package/bin/engine/phases.mjs +24 -2
- package/bin/engine/state.mjs +8 -3
- package/bin/engine-cli.mjs +177 -5
- package/bin/forgedock.mjs +409 -26
- package/bin/hooks/interactive-engine.mjs +509 -0
- package/bin/hooks/pre-tool-use.mjs +498 -0
- package/bin/hooks/subagent-stop-enforce.mjs +197 -0
- package/bin/journey.mjs +72 -14
- package/bin/registry.mjs +139 -0
- package/bin/report.mjs +447 -0
- package/bin/runner.mjs +70 -20
- package/bin/settings-hook.mjs +235 -1
- package/commands/adopt.md +4 -1
- package/commands/analytics.md +4 -1
- package/commands/audit-agents.md +110 -27
- package/commands/audit.md +20 -1
- package/commands/autopilot.md +518 -361
- package/commands/changelog.md +2 -1
- package/commands/ci-audit.md +2 -1
- package/commands/cleanup.md +161 -1
- package/commands/compat-audit.md +2 -1
- package/commands/deploy-info.md +58 -1
- package/commands/deploy-pr.md +485 -0
- package/commands/design-bench.md +5 -1
- package/commands/design-render-critique-loop.md +1 -1
- package/commands/diagnose.md +2 -1
- package/commands/explain.md +2 -1
- package/commands/fix-ci.md +577 -0
- package/commands/forge-stats.md +121 -2
- package/commands/forgedock-init.md +1 -1
- package/commands/geo-audit.md +3 -0
- package/commands/incident-response.md +2 -1
- package/commands/issue.md +23 -2
- package/commands/milestone.md +77 -12
- package/commands/optimize.md +2 -1
- package/commands/orchestrate/config.md +67 -0
- package/commands/orchestrate/phase-1-resolve.md +159 -0
- package/commands/orchestrate/phase-2-triage.md +126 -0
- package/commands/orchestrate/phase-2.5-synthesis.md +156 -0
- package/commands/orchestrate/phase-3-dependency.md +591 -0
- package/commands/orchestrate/phase-4-execution.md +962 -0
- package/commands/orchestrate/phase-5-cleanup.md +47 -0
- package/commands/orchestrate/phase-6-report.md +198 -0
- package/commands/orchestrate/safety.md +62 -0
- package/commands/orchestrate.md +25 -2045
- package/commands/pipeline-health/config.md +34 -0
- package/commands/pipeline-health/phase-1-context.md +180 -0
- package/commands/pipeline-health/phase-2-metrics.md +1729 -0
- package/commands/pipeline-health/phase-3-analyze.md +204 -0
- package/commands/pipeline-health/phase-4-proposals.md +117 -0
- package/commands/pipeline-health/phase-5-report.md +284 -0
- package/commands/pipeline-health/phase-6-summary.md +52 -0
- package/commands/pipeline-health.md +25 -2401
- package/commands/pipeline-resume.md +24 -1
- package/commands/pipeline-status.md +65 -0
- package/commands/qa-sweep.md +4 -1
- package/commands/quality-gate.md +248 -10
- package/commands/recover-orphans.md +576 -0
- package/commands/replay.md +2 -1
- package/commands/review-pr-agents/api.md +135 -0
- package/commands/review-pr-agents/auth.md +137 -0
- package/commands/review-pr-agents/billing.md +101 -0
- package/commands/review-pr-agents/concurrency.md +145 -0
- package/commands/review-pr-agents/database.md +103 -0
- package/commands/review-pr-agents/frontend.md +89 -0
- package/commands/review-pr-agents/infra.md +385 -0
- package/commands/review-pr-agents/protocols.md +185 -0
- package/commands/review-pr-agents/scraper.md +185 -0
- package/commands/review-pr-agents/security.md +406 -0
- package/commands/review-pr-agents.md +45 -1722
- package/commands/review-pr-staging.md +196 -40
- package/commands/review-pr.md +591 -52
- package/commands/rollback.md +2 -1
- package/commands/scope.md +2 -1
- package/commands/security-audit.md +2 -1
- package/commands/signal-planner.md +623 -0
- package/commands/sync-ecosystem.md +1 -0
- package/commands/test-gate.md +17 -1
- package/commands/validate.md +2 -1
- package/commands/work-on/build/architect.md +28 -0
- package/commands/work-on/build/context.md +2 -0
- package/commands/work-on/build/implement.md +3 -1
- package/commands/work-on/build/validate.md +26 -7
- package/commands/work-on/build.md +163 -24
- package/commands/work-on/close.md +130 -3
- package/commands/work-on/decompose.md +19 -1
- package/commands/work-on/investigate.md +117 -2
- package/commands/work-on/review.md +24 -4
- package/commands/work-on-monolithic.md +7 -2
- package/commands/work-on.md +202 -4
- package/docs/BRAND.md +14 -7
- package/docs/CI.md +16 -2
- package/docs/CODEX.md +36 -1
- package/docs/CONFIG.md +5 -8
- package/docs/FORGE-PROTOCOL.md +15 -1064
- package/docs/anthropic-devrel-outreach.md +2 -2
- package/docs/articles/command-decomposition-token-savings.md +214 -0
- package/docs/articles/model-release-playbook.md +131 -0
- package/docs/articles/per-repo-adaptive-scripts-token-savings.md +27 -25
- package/docs/claude-breakpoints.json +75 -5
- package/docs/design/abc-benchmark.md +1 -1
- package/docs/design/design-spec-schema.md +1 -1
- package/docs/design/divergent-generation.md +1 -1
- package/docs/design/eval-gate-runbook.md +178 -0
- package/docs/design/show-hn-draft.md +26 -1
- package/docs/design/token-cost-baseline-1298.md +59 -0
- package/docs/eval/README.md +120 -0
- package/docs/eval/corpus/seed-v1.json +6 -0
- package/docs/eval/published/claude-sonnet-4-6-2026-07-04.json +33 -0
- package/docs/site/annotations-explained.md +24 -0
- package/docs/site/command-learning-path.md +51 -14
- package/docs/site/command-reference.md +386 -111
- package/docs/site/for-companies.md +95 -0
- package/docs/site/forge-annotation-protocol.md +12 -256
- package/docs/site/getting-started.md +43 -4
- package/docs/site/github-is-the-memory.md +113 -0
- package/docs/site/how-it-works.md +3 -13
- package/docs/site/index.md +9 -1
- package/docs/spec/eval-run-result.md +147 -0
- package/docs/spec/forge-protocol-v1.md +441 -18
- package/docs/spec/label-state-machine.md +55 -0
- package/docs/spec/review-protocol.md +158 -0
- package/docs/spec-graph-schema.md +28 -0
- package/docs/superpowers/specs/2026-07-04-economic-self-governance-design.md +181 -0
- package/docs/superpowers/specs/2026-07-04-provenance-trail-design.md +189 -0
- package/examples/forgedock-demo/README.md +41 -22
- package/examples/forgedock-demo/issues/06-bug-tags-type-validation.md +43 -0
- package/examples/forgedock-demo/issues/07-bug-negative-offset-pagination.md +42 -0
- package/examples/forgedock-demo/issues/08-bug-patch-mass-assignment.md +49 -0
- package/examples/forgedock-demo/issues/09-bug-count-injection.md +47 -0
- package/examples/forgedock-demo/issues/10-feature-sort-param.md +39 -0
- package/examples/forgedock-demo/issues/11-feature-patch-tags.md +37 -0
- package/examples/forgedock-demo/issues/12-feature-bulk-create.md +42 -0
- package/examples/forgedock-demo/issues/13-feature-archive-notes.md +46 -0
- package/examples/forgedock-demo/issues/14-refactor-extract-title-validation.md +41 -0
- package/examples/forgedock-demo/issues/15-refactor-protected-route-flag.md +43 -0
- package/examples/forgedock-demo/issues/16-refactor-extract-store.md +45 -0
- package/examples/forgedock-demo/issues/17-perf-tags-dedup-set.md +35 -0
- package/examples/forgedock-demo/issues/18-perf-remove-redundant-sort.md +37 -0
- package/examples/forgedock-demo/issues/19-docs-api-reference-full.md +53 -0
- package/examples/forgedock-demo/issues/20-docs-intentional-flaw-convention.md +46 -0
- package/examples/forgedock-demo/scripts/smoke.js +18 -1
- package/examples/forgedock-demo/src/db.js +36 -11
- package/examples/forgedock-demo/src/routes/notes.js +106 -9
- package/examples/forgedock-demo/src/server.js +4 -1
- package/package.json +3 -1
- package/packages/protocol/LICENSE +21 -0
- package/packages/protocol/src/cli.js +135 -0
- package/packages/protocol/src/emit.js +146 -0
- package/packages/protocol/src/index.js +43 -0
- package/packages/protocol/src/parse.js +254 -0
- package/packages/protocol/src/types.js +171 -0
- package/packages/protocol/src/validate.js +122 -0
- package/scripts/bench-topology-cost.mjs +372 -0
- package/scripts/check-command-docs-drift.sh +198 -0
- package/scripts/check-protocol-restatements.sh +176 -0
- package/scripts/check-registry/README.md +72 -0
- package/scripts/check-registry/manifest.json +6 -0
- package/scripts/code-index.sh +454 -0
- package/scripts/conformance-check.mjs +168 -0
- package/scripts/doctor-pipeline-state.sh +484 -0
- package/scripts/eval-gate-baseline.json +17 -0
- package/scripts/eval-gate-scorecard.mjs +242 -0
- package/scripts/eval-scorecard-aggregator.mjs +252 -0
- package/scripts/flaky-quarantine.sh +241 -0
- package/scripts/forge-annotation.sh +567 -0
- package/scripts/issue-dedup.sh +236 -0
- package/scripts/validate-annotation-node.mjs +233 -0
- package/scripts/worktree-lifecycle.sh +3 -3
- package/templates/devdocs/agent/using-forgedock.md +14 -0
- package/docs/site/.vitepress/config.mjs +0 -85
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Eval Run-Result JSON Schema
|
|
2
|
+
|
|
3
|
+
**Spec version**: 1.0.0
|
|
4
|
+
**Stable since**: issue #1285
|
|
5
|
+
|
|
6
|
+
This document defines the machine-readable JSON shapes consumed and produced by
|
|
7
|
+
the ForgeDock pipeline eval harness:
|
|
8
|
+
|
|
9
|
+
- **Per-run result** — one object per issue, written by the batch driver
|
|
10
|
+
(`bin/batch-runner.mjs`) after each headless `/work-on` run.
|
|
11
|
+
- **Scorecard** — aggregate computed by `scripts/eval-scorecard-aggregator.mjs`
|
|
12
|
+
from an array of per-run results; consumed by the CI regression gate
|
|
13
|
+
(`scripts/eval-gate-scorecard.mjs`, issue #1286) and the publishing pipeline.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Per-Run Result
|
|
18
|
+
|
|
19
|
+
Each headless run of a single corpus issue produces one JSON object:
|
|
20
|
+
|
|
21
|
+
```jsonc
|
|
22
|
+
{
|
|
23
|
+
// Required fields
|
|
24
|
+
"issue": 1234, // integer — GitHub issue number
|
|
25
|
+
"status": "success", // "success" | "failure" | "incomplete" | "error"
|
|
26
|
+
"wallClockMs": 42000, // integer — wall-clock duration of the run (ms)
|
|
27
|
+
"interventionCount": 0, // integer — number of human interventions (see below)
|
|
28
|
+
|
|
29
|
+
// Optional fields (nullable — do NOT block on missing upstream data)
|
|
30
|
+
"cost": null, // null | number — token/USD cost; null until #1255 lands
|
|
31
|
+
"iterations": 23, // integer — tool-use loop iteration count
|
|
32
|
+
"stopReason": "end_turn", // string — Anthropic stop_reason or "max_iterations"
|
|
33
|
+
"error": null, // null | string — error message when status === "error"
|
|
34
|
+
"specVersion": "1.0.21", // string — forgedock package version at run time
|
|
35
|
+
"model": "claude-sonnet-4-5", // string — model used for the run
|
|
36
|
+
"runAt": "2026-07-04T00:00:00.000Z" // ISO-8601 timestamp
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### `status` values
|
|
41
|
+
|
|
42
|
+
| Value | Meaning |
|
|
43
|
+
|--------------|------------------------------------------------------------------------------|
|
|
44
|
+
| `success` | Run completed; the issue reached `workflow:merged` or equivalent terminal state |
|
|
45
|
+
| `failure` | Run completed but the issue did not reach a terminal success state |
|
|
46
|
+
| `incomplete` | Run stopped due to `max_tokens` or `max_iterations` — result is unreliable |
|
|
47
|
+
| `error` | The runner threw an unhandled exception (network, API, crash) |
|
|
48
|
+
|
|
49
|
+
### `interventionCount` definition
|
|
50
|
+
|
|
51
|
+
A human intervention is counted when **any** of the following occur during a run:
|
|
52
|
+
|
|
53
|
+
1. The `needs-human` label is applied to the issue by the pipeline.
|
|
54
|
+
2. A manual `gh` command is executed outside the automated runner loop.
|
|
55
|
+
3. A FORGE annotation comment is posted by a human (not the bot account) during the run window.
|
|
56
|
+
|
|
57
|
+
Runs where no human interaction occurs have `interventionCount: 0`.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Batch Driver Output File
|
|
62
|
+
|
|
63
|
+
`bin/batch-runner.mjs` writes a JSON object containing the per-run array plus
|
|
64
|
+
top-level metadata:
|
|
65
|
+
|
|
66
|
+
```jsonc
|
|
67
|
+
{
|
|
68
|
+
"corpus_version": "v1", // string | null — corpus version label
|
|
69
|
+
"spec_version": "1.0.21", // string | null — forgedock version at run time
|
|
70
|
+
"model": "claude-sonnet-4-5", // string | null — model used
|
|
71
|
+
"generated_at": "2026-07-04T00:00:00.000Z",
|
|
72
|
+
"runs": [ ...PerRunResult ]
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Corpus File
|
|
79
|
+
|
|
80
|
+
The batch driver accepts a corpus file (JSON) listing issues to run:
|
|
81
|
+
|
|
82
|
+
```jsonc
|
|
83
|
+
{
|
|
84
|
+
"corpus_version": "v1", // string — semver or label for the corpus snapshot
|
|
85
|
+
"run_id": "run-2026-07-04-1", // string — optional unique run identifier
|
|
86
|
+
"run_mode": "full", // "full" | "subset" — passed through to scorecard
|
|
87
|
+
"spec_sha": "abc123", // string | null — git SHA of commands/ at run time
|
|
88
|
+
"issues": [1001, 1002, 1003] // integer[] — GitHub issue numbers
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Scorecard
|
|
95
|
+
|
|
96
|
+
`scripts/eval-scorecard-aggregator.mjs` reads the batch driver output and emits
|
|
97
|
+
a scorecard in the format consumed by `scripts/eval-gate-scorecard.mjs` (#1286):
|
|
98
|
+
|
|
99
|
+
```jsonc
|
|
100
|
+
{
|
|
101
|
+
"schema_version": "1", // string — always "1" (schema identifier)
|
|
102
|
+
"run_id": "run-2026-07-04-1", // string | null — from corpus metadata
|
|
103
|
+
"generated_at": "2026-07-04T00:00:00.000Z",
|
|
104
|
+
"corpus_size": 20, // integer — from corpus metadata (defaults to issues_run)
|
|
105
|
+
"issues_run": 20, // integer — total runs in the input
|
|
106
|
+
"successful_runs": 17, // integer — runs with status === "success"
|
|
107
|
+
"failed_runs": 2, // integer — runs with status === "failure"
|
|
108
|
+
"success_rate_pct": 85, // number [0,100] — successful_runs / issues_run * 100 (2dp)
|
|
109
|
+
"mean_wall_clock_ms": 38200, // number | null — arithmetic mean wall-clock
|
|
110
|
+
"median_wall_clock_ms": 35000, // number | null — median wall-clock
|
|
111
|
+
"total_intervention_count": 1, // integer — sum of interventionCount across all runs
|
|
112
|
+
"cost": null, // null | number — sum of per-run cost; null if any run has cost: null
|
|
113
|
+
"run_mode": "full", // "full" | "subset"
|
|
114
|
+
"spec_sha": "abc123" // string | null — git SHA of commands/ at run time
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Important**: `incomplete` and `error` status runs count against `success_rate_pct`
|
|
119
|
+
(they reduce `issues_run` denominator's numerator). This ensures the gate catches
|
|
120
|
+
hangs and crashes, not just logic failures.
|
|
121
|
+
|
|
122
|
+
### Methodology rules (enforced by the scorecard aggregator)
|
|
123
|
+
|
|
124
|
+
1. **Minimum sample size**: fewer than `MIN_RUNS` (currently **5**) scoreable
|
|
125
|
+
(`success` or `failure`) runs causes the aggregator to exit non-zero rather
|
|
126
|
+
than emit a misleading rate. Mirrors `bench-scorecard.mjs`'s `MIN_RUNS` rule.
|
|
127
|
+
2. **Malformed input**: missing required fields (`issue`, `status`,
|
|
128
|
+
`wallClockMs`, `interventionCount`) or non-integer/non-string values cause
|
|
129
|
+
exit code 1 (validation error).
|
|
130
|
+
3. **Cost is nullable**: if any run has `cost: null`, the scorecard's
|
|
131
|
+
`cost` is `null`. The field becomes numeric only when every run reports a
|
|
132
|
+
real cost value (post-#1255).
|
|
133
|
+
4. **Rate consistency**: `success_rate_pct` is always computed as
|
|
134
|
+
`round(successful_runs / issues_run * 100, 2)`. The CI gate (#1286) validates
|
|
135
|
+
this computed value matches the reported value.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Stability contract
|
|
140
|
+
|
|
141
|
+
- Field names are stable. New **optional** fields may be added at any time
|
|
142
|
+
without a version bump.
|
|
143
|
+
- Removing or renaming a field is a breaking change and requires a spec version
|
|
144
|
+
bump and a GitHub issue.
|
|
145
|
+
- Consumers **must** treat unknown fields as ignorable (forward-compatibility).
|
|
146
|
+
- The CI gate sub-issue (#1286) and publishing sub-issue (#1287) may depend on
|
|
147
|
+
this schema without waiting for upstream changes.
|
|
@@ -453,6 +453,15 @@ artifact so a sub-issue builder can fetch upstream context directly.
|
|
|
453
453
|
|
|
454
454
|
These markers carry no Markdown body; their presence is the signal.
|
|
455
455
|
|
|
456
|
+
**Phase boundary markers** (appear in pipeline command specs):
|
|
457
|
+
|
|
458
|
+
| Marker | Meaning |
|
|
459
|
+
|--------|---------|
|
|
460
|
+
| `<!-- FORGE:DISPATCHER — {desc} -->` | Marks the Universal Phase Dispatcher — the single source of truth for phase transitions and routing logic |
|
|
461
|
+
| `<!-- FORGE:PHASE_COMPLETE — {desc} -->` | Inter-phase boundary; documents that a phase completed and names the next phase so agents do not treat an intermediate result as terminal |
|
|
462
|
+
|
|
463
|
+
**Issue-comment control markers** (posted to issue comments):
|
|
464
|
+
|
|
456
465
|
| Marker | Meaning |
|
|
457
466
|
|--------|---------|
|
|
458
467
|
| `<!-- FORGE:REVIEW_STARTED -->` | The review phase has been invoked for this issue |
|
|
@@ -466,6 +475,255 @@ needed.
|
|
|
466
475
|
|
|
467
476
|
---
|
|
468
477
|
|
|
478
|
+
### 4.4 Design pipeline annotations
|
|
479
|
+
|
|
480
|
+
These annotations drive the UI Taste Harness — the design-generation pipeline
|
|
481
|
+
that produces a landing page from a design-blind product brief. They carry
|
|
482
|
+
design intent across the investigate → architect → generate → critique → close
|
|
483
|
+
stages, exactly as the lifecycle annotations carry code context across
|
|
484
|
+
investigate → build → review.
|
|
485
|
+
|
|
486
|
+
#### `FORGE:DESIGN_CONTEXT`
|
|
487
|
+
|
|
488
|
+
- **Written by**: the `/design` design-investigate stage
|
|
489
|
+
- **Read by**: design-architect stage (grounds the rationale), close phase (audit trail)
|
|
490
|
+
- **Completion sentinel**: `<!-- FORGE:DESIGN_CONTEXT:COMPLETE -->`
|
|
491
|
+
|
|
492
|
+
The design analog of `FORGE:CONTEXT`: the parsed brief (message / audience /
|
|
493
|
+
single objection), the grammar pulled from the reference corpus, and the recent
|
|
494
|
+
signature moves / archetypes / palettes from design-memory that this design must
|
|
495
|
+
diverge from. Opens the `FORGE:DESIGN_*` chain.
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
<!-- FORGE:DESIGN_CONTEXT -->
|
|
499
|
+
## Design Context — {product}
|
|
500
|
+
|
|
501
|
+
**Message:** {one thing the page must say}
|
|
502
|
+
**Audience / objection:** {who} — must overcome: {objection}
|
|
503
|
+
**Corpus grammar:** {relevant traits / archetype priors}
|
|
504
|
+
**Diverge from (memory):** {recent signature moves / archetypes / palettes to avoid}
|
|
505
|
+
<!-- FORGE:DESIGN_CONTEXT:COMPLETE -->
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
#### `FORGE:DESIGN_RATIONALE`
|
|
509
|
+
|
|
510
|
+
- **Written by**: the design-architect agent
|
|
511
|
+
- **Read by**: the generate agent (the spec it produces), the render → vision-critique loop, and reviewers
|
|
512
|
+
- **Emitted**: before `FORGE:DESIGN_SPEC`
|
|
513
|
+
|
|
514
|
+
The designer's diary — the reasoning-before-generation step. Captures a
|
|
515
|
+
seven-element chain of thought (intent/feeling, audience/objection,
|
|
516
|
+
communication hierarchy, direction + rejected alternatives, signature move,
|
|
517
|
+
what's being tried this time, non-goals). MUST carry at least one explicitly
|
|
518
|
+
rejected alternative, a named signature move, and a `→ Produces DESIGN_SPEC`
|
|
519
|
+
link.
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
<!-- FORGE:DESIGN_RATIONALE -->
|
|
523
|
+
## Design Rationale — {product}
|
|
524
|
+
|
|
525
|
+
**Intent / feeling:** {one message} · {one feeling}
|
|
526
|
+
**Audience / objection:** {who} — must overcome: {objection}
|
|
527
|
+
**Communication hierarchy:** 1) {…} 2) {…} 3) {…}
|
|
528
|
+
**Direction:** {archetype} — because {reasoning}
|
|
529
|
+
- Considered & rejected: {alt A} (because {…}); {alt B} (because {…})
|
|
530
|
+
**Signature move:** {the one non-obvious idea}
|
|
531
|
+
**Trying this time:** {technique/learning} (from memory: avoiding {prior move})
|
|
532
|
+
**Non-goals:** {what this won't do}
|
|
533
|
+
|
|
534
|
+
→ Produces DESIGN_SPEC: {link}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
#### `FORGE:DESIGN_CANDIDATES`
|
|
538
|
+
|
|
539
|
+
- **Written by**: the generate agent (divergent-generation step)
|
|
540
|
+
- **Read by**: the taste-judge (selects the winner), close phase (audit trail), design-memory (to diverge from past winners)
|
|
541
|
+
- **Emitted**: after `FORGE:DESIGN_RATIONALE`, before `FORGE:DESIGN_SPEC`
|
|
542
|
+
|
|
543
|
+
The variance lever's audit record: the one committed archetype (never blended),
|
|
544
|
+
the N distinct directions generated within it, and the independent taste-judge's
|
|
545
|
+
scores and selection. The selection judge is distinct from the critique loop —
|
|
546
|
+
anti-Goodhart.
|
|
547
|
+
|
|
548
|
+
```
|
|
549
|
+
<!-- FORGE:DESIGN_CANDIDATES -->
|
|
550
|
+
## Design Candidates — {product}
|
|
551
|
+
|
|
552
|
+
**Archetype (committed):** {one of the corpus ids}
|
|
553
|
+
**Directions:**
|
|
554
|
+
1. {concept} — signature: {move} — {distinguishing grammar/tokens}
|
|
555
|
+
2. {concept} — signature: {move} — {…}
|
|
556
|
+
**Judge scores:** 1) {score} 2) {score} …
|
|
557
|
+
**Selected:** #{n} — because {reason}
|
|
558
|
+
|
|
559
|
+
→ Winner produces DESIGN_SPEC: {link}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
#### `FORGE:DESIGN_SPEC`
|
|
563
|
+
|
|
564
|
+
- **Written by**: the design-architect agent
|
|
565
|
+
- **Read by**: the generate agent (constrains output), the deterministic anti-slop linter, the render → vision-critique loop, and the close phase agent
|
|
566
|
+
|
|
567
|
+
A structured, machine-checkable representation of one page's design language.
|
|
568
|
+
Produced by `FORGE:DESIGN_RATIONALE` — not authored from nowhere. The flow is
|
|
569
|
+
rationale → spec → page. Full field-by-field schema lives in
|
|
570
|
+
`docs/design/design-spec-schema.md`.
|
|
571
|
+
|
|
572
|
+
````
|
|
573
|
+
<!-- FORGE:DESIGN_SPEC -->
|
|
574
|
+
## Design Spec — {product}
|
|
575
|
+
|
|
576
|
+
```jsonc
|
|
577
|
+
{
|
|
578
|
+
"meta": { "product": "…", "archetype": "…", "corpus_version": "…", "rationale_ref": "…" },
|
|
579
|
+
"typography": { "display_family": "…", "body_family": "…", "scale_ratio": …, "weights": […] },
|
|
580
|
+
"color": { "mode": "…", "background": "#…", "foreground": "#…", "accent": "#…",
|
|
581
|
+
"rules": ["no-default-tailwind-palette", "contrast>=4.5"] },
|
|
582
|
+
"spacing": { "base_unit_px": …, "scale": […] },
|
|
583
|
+
"radius": { "scale": […] },
|
|
584
|
+
"shadow": { "tokens": […] },
|
|
585
|
+
"motion": { "vocabulary": […], "reduced_motion": "required" },
|
|
586
|
+
"layout_grammar":{ "sections": [ { "id": "…", "purpose": "…", "density": "…" } ], "rhythm": "…" },
|
|
587
|
+
"effects_plan": { "per_section": [ … ], "budget": { … }, "never": [ … ] },
|
|
588
|
+
"negatives": [ … ],
|
|
589
|
+
"acceptance": { "perf_budget": { … }, "a11y": { … }, "divergence_ref": "…" }
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
→ Produced by FORGE:DESIGN_RATIONALE: {link}
|
|
594
|
+
````
|
|
595
|
+
|
|
596
|
+
#### `FORGE:CRITIQUE`
|
|
597
|
+
|
|
598
|
+
- **Written by**: the vision-critique loop (one annotation per iteration)
|
|
599
|
+
- **Read by**: the iterate step (consumes its findings), close phase (improvement trajectory audit)
|
|
600
|
+
- **Completion sentinel**: `<!-- FORGE:CRITIQUE:COMPLETE -->`
|
|
601
|
+
|
|
602
|
+
One annotation per render → critique iteration — the page's improvement
|
|
603
|
+
trajectory as an auditable trail. Records the deterministic lint floor result,
|
|
604
|
+
the desktop+mobile render, the perceptual findings, and the verdict. The critic
|
|
605
|
+
is strictly independent from the benchmark judge — anti-Goodhart.
|
|
606
|
+
|
|
607
|
+
```
|
|
608
|
+
<!-- FORGE:CRITIQUE -->
|
|
609
|
+
## Critique — {product} · iteration {i}/{max}
|
|
610
|
+
|
|
611
|
+
**Lint floor:** {PASS | fixed N hard findings}
|
|
612
|
+
**Render:** desktop + mobile captured
|
|
613
|
+
**Perceptual findings:**
|
|
614
|
+
- N{n}: {what was observed in the render} → {correction}
|
|
615
|
+
**Verdict:** {PASS | ITERATE | BUDGET-EXHAUSTED}
|
|
616
|
+
<!-- FORGE:CRITIQUE:COMPLETE -->
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
#### `FORGE:USER_FEEDBACK`
|
|
620
|
+
|
|
621
|
+
- **Written by**: the `/design` user-feedback stage
|
|
622
|
+
- **Read by**: the surgical re-generation step, close phase (audit trail)
|
|
623
|
+
- **Completion sentinel**: `<!-- FORGE:USER_FEEDBACK:COMPLETE -->`
|
|
624
|
+
- **Not produced** in automated (benchmark) runs
|
|
625
|
+
|
|
626
|
+
The structured record of one user-feedback round. There MAY be multiple
|
|
627
|
+
`FORGE:USER_FEEDBACK` annotations on a single issue if the user iterates.
|
|
628
|
+
`FORGE:USER_FEEDBACK` MAY modify a section's visual execution but MUST NOT
|
|
629
|
+
change the committed `meta.archetype` or the signature move from
|
|
630
|
+
`FORGE:DESIGN_RATIONALE` — those choices are locked once the spec is committed.
|
|
631
|
+
|
|
632
|
+
```
|
|
633
|
+
<!-- FORGE:USER_FEEDBACK -->
|
|
634
|
+
## User Feedback — {product} · round {n}
|
|
635
|
+
|
|
636
|
+
**Section target:** {section ID from layout_grammar.sections, or "all" for page-wide feedback}
|
|
637
|
+
**Feedback type:** {asset | emotion | direction | freeform}
|
|
638
|
+
**Asset URL:** {URL or "none"}
|
|
639
|
+
**Modification:** {structured description of what to change}
|
|
640
|
+
**Emotion target:** {trust | speed | power | craft | play | unchanged}
|
|
641
|
+
**Satisfied:** {yes | no — "no" loops back after re-generation}
|
|
642
|
+
**Freeform notes:** {verbatim user input not captured in the structured fields}
|
|
643
|
+
<!-- FORGE:USER_FEEDBACK:COMPLETE -->
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
#### `FORGE:BENCH_SCORECARD`
|
|
647
|
+
|
|
648
|
+
- **Written by**: the `/design-bench` benchmark rig
|
|
649
|
+
- **Read by**: harness developers (fitness signal), milestone tracker, pipeline-health
|
|
650
|
+
- **Completion sentinel**: `<!-- FORGE:BENCH_SCORECARD:COMPLETE -->`
|
|
651
|
+
|
|
652
|
+
The result of one ABC benchmark run. Arm A is the harness output, arm B is a
|
|
653
|
+
raw one-shot model, arm C is the real reference page (gold standard). The
|
|
654
|
+
annotation carries win-rates, the A-vs-B harness delta, rubric distributions
|
|
655
|
+
(mean + stdev) across n≥3 runs, mean slop counts, and a judge-calibration check
|
|
656
|
+
(C must beat A and B — otherwise the judge is miscalibrated).
|
|
657
|
+
|
|
658
|
+
````
|
|
659
|
+
<!-- FORGE:BENCH_SCORECARD -->
|
|
660
|
+
## ABC Benchmark Scorecard
|
|
661
|
+
|
|
662
|
+
**Corpus version**: {ver} · **Generation model (A & B)**: {model} · **Judge model**: {independent judge}
|
|
663
|
+
**Products**: {n_products} · **Runs/product**: {n}
|
|
664
|
+
|
|
665
|
+
| Arm | Win-rate vs C | A-vs-B | Mean slop |
|
|
666
|
+
|-----|---------------|--------|-----------|
|
|
667
|
+
| A | {wr} | {a_vs_b} | {slop_A} |
|
|
668
|
+
| B | {wr} | — | {slop_B} |
|
|
669
|
+
|
|
670
|
+
**Judge calibration**: {ok | MISCALIBRATED — N runs where C lost (suspect)}
|
|
671
|
+
|
|
672
|
+
```json
|
|
673
|
+
{scorecard.json from bench-scorecard.mjs}
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
<!-- FORGE:BENCH_SCORECARD:COMPLETE -->
|
|
677
|
+
````
|
|
678
|
+
|
|
679
|
+
#### `FORGE:DESIGN_SHIPPED`
|
|
680
|
+
|
|
681
|
+
- **Written by**: the `/design` design-close stage
|
|
682
|
+
- **Read by**: design-memory (persists the realized outcome), milestone tracker, pipeline-health
|
|
683
|
+
- **Completion sentinel**: `<!-- FORGE:DESIGN_SHIPPED:COMPLETE -->`
|
|
684
|
+
- **Terminal annotation** for the design pipeline (analogous to `workflow:merged` for code)
|
|
685
|
+
|
|
686
|
+
Closes the design pipeline. Posted only when the design passes the full
|
|
687
|
+
definition of done — critique-rubric threshold, perf budget, a11y check, and
|
|
688
|
+
the divergence check. Records the final realized outcome written to design-memory
|
|
689
|
+
so the next design can diverge from it.
|
|
690
|
+
|
|
691
|
+
```
|
|
692
|
+
<!-- FORGE:DESIGN_SHIPPED -->
|
|
693
|
+
## Design Shipped — {product}
|
|
694
|
+
|
|
695
|
+
**Archetype:** {committed id} · **Signature move:** {the hook}
|
|
696
|
+
**Gates:** rubric {pass} · perf {pass} · a11y {pass} · divergence {distinct from prior}
|
|
697
|
+
**Critique iterations:** {n}
|
|
698
|
+
**Written to memory:** {palette/type/effects/learnings summary}
|
|
699
|
+
<!-- FORGE:DESIGN_SHIPPED:COMPLETE -->
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
---
|
|
703
|
+
|
|
704
|
+
### 4.5 Audit annotations
|
|
705
|
+
|
|
706
|
+
These annotations are posted to issue or PR comments by audit commands
|
|
707
|
+
(`/audit`, `/audit-agents`, `/security-audit`) after running structured code
|
|
708
|
+
audits.
|
|
709
|
+
|
|
710
|
+
#### `FORGE:AUDIT`
|
|
711
|
+
|
|
712
|
+
- **Written by**: audit command agents (`/audit`, `/audit-agents`)
|
|
713
|
+
- **Location**: issue or PR comment
|
|
714
|
+
|
|
715
|
+
Posted after running a structured code or agent audit. Body content varies by
|
|
716
|
+
audit type.
|
|
717
|
+
|
|
718
|
+
#### `FORGE:SECURITY_AUDIT`
|
|
719
|
+
|
|
720
|
+
- **Written by**: the `/security-audit` command
|
|
721
|
+
- **Location**: issue comment
|
|
722
|
+
|
|
723
|
+
Posted after completing a 4-phase security posture audit.
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
469
727
|
## 5. The Context Chain
|
|
470
728
|
|
|
471
729
|
Lifecycle annotations form an ordered chain. Each stage reads the outputs of all
|
|
@@ -512,22 +770,11 @@ Annotations record *what happened*; labels record *where a unit of work is* so a
|
|
|
512
770
|
consumer can determine the current stage without reading every comment. The
|
|
513
771
|
protocol reserves the `workflow:` label namespace:
|
|
514
772
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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.
|
|
773
|
+
> **Canonical reference**: [`docs/spec/label-state-machine.md`](label-state-machine.md)
|
|
774
|
+
>
|
|
775
|
+
> The full state table, transition diagram, terminal labels, and label-exclusivity
|
|
776
|
+
> pattern are defined there. Labels and annotations are complementary: labels give
|
|
777
|
+
> a fast state lookup, annotations give the full context behind that state.
|
|
531
778
|
|
|
532
779
|
---
|
|
533
780
|
|
|
@@ -739,7 +986,141 @@ which tool or model produced it — interoperates with this consumer unchanged.
|
|
|
739
986
|
|
|
740
987
|
---
|
|
741
988
|
|
|
742
|
-
## 10.
|
|
989
|
+
## 10. Nested-Command Decomposition Pattern
|
|
990
|
+
|
|
991
|
+
Large command specs that grow past ~50 KB become expensive to load in full on
|
|
992
|
+
every invocation, even when a given run only exercises a fraction of the spec's
|
|
993
|
+
surface. The **nested-command decomposition pattern** addresses this by splitting
|
|
994
|
+
a large spec into a top-level file and one or more supporting sub-files in a
|
|
995
|
+
subdirectory of the same name.
|
|
996
|
+
|
|
997
|
+
### 10.1 When to decompose
|
|
998
|
+
|
|
999
|
+
Decompose a command spec into a `commands/<name>/` directory when **any two** of
|
|
1000
|
+
the following are true:
|
|
1001
|
+
|
|
1002
|
+
- The spec file exceeds **~30 KB** (token budget becomes significant).
|
|
1003
|
+
- The spec has **two or more separable sub-phases** that are only reached along
|
|
1004
|
+
specific execution paths (e.g., a build phase that is skipped for trivial
|
|
1005
|
+
tasks).
|
|
1006
|
+
- The spec delegates to **distinct named skill scopes** (e.g.,
|
|
1007
|
+
`work-on:build:context`, `work-on:build:architect`) that have their own
|
|
1008
|
+
input/output contracts.
|
|
1009
|
+
- The spec is invoked by other commands that benefit from loading only a subset
|
|
1010
|
+
of its logic (e.g., `orchestrate` spawns `work-on` but only needs its outer
|
|
1011
|
+
routing logic, not every inline sub-phase).
|
|
1012
|
+
|
|
1013
|
+
Do **not** decompose for organizational preference alone. Every subdirectory
|
|
1014
|
+
adds a graph node and must be maintained when the parent spec changes. If a spec
|
|
1015
|
+
is small and its phases are always executed together, keep it as a single file.
|
|
1016
|
+
|
|
1017
|
+
### 10.2 Naming convention
|
|
1018
|
+
|
|
1019
|
+
```
|
|
1020
|
+
commands/
|
|
1021
|
+
work-on.md ← top-level entry point (dispatcher + universal rules)
|
|
1022
|
+
work-on/ ← sub-specs, same name as the top-level file
|
|
1023
|
+
build.md ← sub-command (invocable as work-on:build)
|
|
1024
|
+
build/ ← sub-sub-specs for build
|
|
1025
|
+
context.md
|
|
1026
|
+
architect.md
|
|
1027
|
+
implement.md
|
|
1028
|
+
validate.md
|
|
1029
|
+
investigate.md
|
|
1030
|
+
review.md
|
|
1031
|
+
close.md
|
|
1032
|
+
decompose.md
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
Rules:
|
|
1036
|
+
- The subdirectory name **MUST** match the stem of the top-level spec file
|
|
1037
|
+
(e.g., `work-on.md` → `work-on/`).
|
|
1038
|
+
- Sub-files are named after the sub-phase they implement (lowercase,
|
|
1039
|
+
hyphenated). They are invocable as `<parent>:<sub-file-stem>` via the Skill
|
|
1040
|
+
tool (e.g., `Skill(skill="work-on:build:context", ...)`).
|
|
1041
|
+
- Sub-files that go to depth 3 (e.g., `work-on/build/context.md`) follow the
|
|
1042
|
+
same pattern recursively: their subdirectory is `work-on/build/context/` if
|
|
1043
|
+
further decomposition is ever needed.
|
|
1044
|
+
|
|
1045
|
+
### 10.3 Automatic pick-up by the installer and graph
|
|
1046
|
+
|
|
1047
|
+
No manual registration is required. Two mechanisms pick up sub-files
|
|
1048
|
+
automatically:
|
|
1049
|
+
|
|
1050
|
+
**Installer (`bin/forgedock.mjs`)**: The `findMarkdownFiles()` helper performs a
|
|
1051
|
+
recursive directory walk over `commands/` (skipping `node_modules` and
|
|
1052
|
+
dot-directories). Every `.md` file discovered — at any depth — is symlinked into
|
|
1053
|
+
`~/.claude/commands/` at the same relative path. A file at
|
|
1054
|
+
`commands/work-on/build/context.md` is installed as
|
|
1055
|
+
`~/.claude/commands/work-on/build/context.md`, making it reachable by Claude
|
|
1056
|
+
Code's Skill resolver as `work-on:build:context`.
|
|
1057
|
+
|
|
1058
|
+
**Spec graph builder (`scripts/build-spec-graph.mjs`)**: The `walk()` function
|
|
1059
|
+
in the builder performs the same recursive directory walk over `commands/`,
|
|
1060
|
+
discovering all spec files regardless of nesting depth. Each discovered file
|
|
1061
|
+
becomes a graph node. The `load-set` query uses `CONTAINS` edges (written when a
|
|
1062
|
+
parent spec references a sub-spec via `Skill()`) to resolve the minimal spec set
|
|
1063
|
+
for a given entry command.
|
|
1064
|
+
|
|
1065
|
+
### 10.4 Token-saving effect
|
|
1066
|
+
|
|
1067
|
+
Because the installer symlinks sub-specs at their actual nested paths, Claude
|
|
1068
|
+
Code's selective spec loading (Phase 0 of `/work-on`) can load each sub-spec
|
|
1069
|
+
only when execution reaches that sub-phase — skipped sub-phases contribute zero
|
|
1070
|
+
tokens to the session context. The spec knowledge graph's `load-set` query
|
|
1071
|
+
computes the minimal reachable set from the entry command, excluding sub-specs
|
|
1072
|
+
that are never reached by that command's execution graph.
|
|
1073
|
+
|
|
1074
|
+
The measured token savings from decomposing `/work-on` and applying
|
|
1075
|
+
`load-set`-driven selective loading are documented in
|
|
1076
|
+
`docs/articles/command-decomposition-token-savings.md`. The same methodology
|
|
1077
|
+
can be applied to any command spec that meets the decomposition criteria in
|
|
1078
|
+
Section 10.1.
|
|
1079
|
+
|
|
1080
|
+
---
|
|
1081
|
+
|
|
1082
|
+
## 11. Adopting FORGE in Your Own Pipeline <!-- renumbered from §10 -->
|
|
1083
|
+
|
|
1084
|
+
FORGE is an open format. Any tool that can read and write platform comments can
|
|
1085
|
+
participate — no dependency on a specific framework, model, or vendor.
|
|
1086
|
+
|
|
1087
|
+
**Minimum viable adoption**:
|
|
1088
|
+
|
|
1089
|
+
1. Pick the annotation types relevant to your pipeline (`FORGE:INVESTIGATOR` +
|
|
1090
|
+
`FORGE:BUILDER` is a good starting point).
|
|
1091
|
+
2. Write your agent prompts to post annotated comments after each phase.
|
|
1092
|
+
3. Write downstream agent prompts to read those comments before starting.
|
|
1093
|
+
|
|
1094
|
+
**Implementation checklist**:
|
|
1095
|
+
|
|
1096
|
+
1. **Read existing annotations** before starting work on an issue:
|
|
1097
|
+
|
|
1098
|
+
```bash
|
|
1099
|
+
gh api repos/{OWNER}/{REPO}/issues/{NUMBER}/comments \
|
|
1100
|
+
--jq '.[] | select(.body | contains("FORGE:")) | {id: .id, body: .body}'
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
2. **Write annotations** using the schemas in Section 4 after completing each phase.
|
|
1104
|
+
|
|
1105
|
+
3. **Check for existing annotations** before writing (idempotency):
|
|
1106
|
+
|
|
1107
|
+
```bash
|
|
1108
|
+
EXISTING=$(gh api repos/{OWNER}/{REPO}/issues/{NUMBER}/comments \
|
|
1109
|
+
--jq '.[] | select(
|
|
1110
|
+
.body | (contains("FORGE:INVESTIGATOR") and contains("INVESTIGATION:COMPLETE"))
|
|
1111
|
+
) | .id')
|
|
1112
|
+
if [ -n "$EXISTING" ]; then echo "Already investigated — skip"; fi
|
|
1113
|
+
```
|
|
1114
|
+
|
|
1115
|
+
4. **Respect label state** — check `workflow:*` labels (Section 6) to determine
|
|
1116
|
+
the current phase and whether the work item is in a terminal state.
|
|
1117
|
+
|
|
1118
|
+
5. **Use text-contains filtering** as the primary query interface. All FORGE
|
|
1119
|
+
implementations can assume `gh api` or equivalent is available.
|
|
1120
|
+
|
|
1121
|
+
---
|
|
1122
|
+
|
|
1123
|
+
## 12. Versioning
|
|
743
1124
|
|
|
744
1125
|
This document specifies **version 1.0**.
|
|
745
1126
|
|
|
@@ -754,7 +1135,36 @@ Annotations do not carry an explicit version field. Conforming consumers
|
|
|
754
1135
|
|
|
755
1136
|
---
|
|
756
1137
|
|
|
757
|
-
##
|
|
1138
|
+
## 13. Reference Implementation
|
|
1139
|
+
|
|
1140
|
+
The canonical reference implementation of this specification is published as a
|
|
1141
|
+
separate, MIT-licensed npm package:
|
|
1142
|
+
|
|
1143
|
+
**`@forgedock/protocol`** — available at `packages/protocol/` in the ForgeDock
|
|
1144
|
+
repository.
|
|
1145
|
+
|
|
1146
|
+
It provides:
|
|
1147
|
+
|
|
1148
|
+
- `parse(commentBody)` — extracts all annotations from a comment body string
|
|
1149
|
+
- `validate(annotation)` — checks conformance per §3–4; returns `{ valid, errors, warnings }`
|
|
1150
|
+
- `emit(type, fields)` — produces well-formed annotation strings
|
|
1151
|
+
- `emitPartial(type)` — produces the partial sentinel for a type (§3.3)
|
|
1152
|
+
|
|
1153
|
+
A conformance suite in `packages/protocol/fixtures/` covers all 13 reserved
|
|
1154
|
+
types with valid and invalid examples. The CLI runner can be invoked against any
|
|
1155
|
+
fixtures directory:
|
|
1156
|
+
|
|
1157
|
+
```bash
|
|
1158
|
+
npx @forgedock/protocol fixtures/
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
**Library version and spec version move together**: a library at version `1.x`
|
|
1162
|
+
implements spec version 1.0. Breaking spec changes (§11, major revisions)
|
|
1163
|
+
require a library major version bump.
|
|
1164
|
+
|
|
1165
|
+
---
|
|
1166
|
+
|
|
1167
|
+
## 14. Acknowledgements
|
|
758
1168
|
|
|
759
1169
|
The FORGE Annotation Protocol was first developed and proven in a production
|
|
760
1170
|
autonomous-development pipeline, where it coordinated investigator, builder,
|
|
@@ -762,6 +1172,19 @@ and reviewer agents across tens of thousands of issues. This specification
|
|
|
762
1172
|
generalizes that wire format into a tool-neutral, openly licensed standard so
|
|
763
1173
|
that any agent pipeline can adopt and interoperate with it.
|
|
764
1174
|
|
|
1175
|
+
### Conformance note — Codex adapter (second implementation)
|
|
1176
|
+
|
|
1177
|
+
The Codex-native adapter (`.agents/skills/*/SKILL.md` in the ForgeDock
|
|
1178
|
+
repository) constitutes a second independent implementation of this protocol.
|
|
1179
|
+
It reads the same `commands/*.md` workflow specs and produces/consumes FORGE
|
|
1180
|
+
annotations through a different runtime (different tool calls, different
|
|
1181
|
+
worktree paths, different repo-resolution conventions) than the Claude Code
|
|
1182
|
+
path. Both implementations have been validated against
|
|
1183
|
+
`scripts/conformance-check.mjs`, the repository's automated conformance suite
|
|
1184
|
+
for this specification. This provides concrete evidence of vendor neutrality —
|
|
1185
|
+
the wire format is not incidentally compatible with one runtime; it functions
|
|
1186
|
+
as designed across distinct agent frameworks.
|
|
1187
|
+
|
|
765
1188
|
---
|
|
766
1189
|
|
|
767
1190
|
*FORGE Annotation Protocol v1.0 — released under
|