@cassiomc1/forgeloop 1.2.3 → 1.3.0
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/AGENT_COMPATIBILITY.md +4 -0
- package/DOCS_INDEX.md +7 -0
- package/EXECUTION_STATE.md +8 -0
- package/LOOP_ENGINEERING.md +1 -1
- package/LOOP_SYSTEM_DESIGN.md +10 -0
- package/PROTOCOL_INTEGRATION.md +30 -0
- package/README.md +48 -0
- package/THREAT_MODEL.md +3 -1
- package/docs/ARTIFACT_REFERENCE.md +11 -0
- package/docs/CLI_REFERENCE.md +81 -3
- package/docs/CROSS_HARNESS_CONTINUITY.md +11 -0
- package/docs/DOCUMENTATION_GUIDE.md +17 -0
- package/docs/GETTING_STARTED.md +9 -0
- package/docs/RECIPES.md +5 -1
- package/docs/TROUBLESHOOTING.md +133 -40
- package/package.json +4 -1
- package/schemas/execution.schema.json +11 -1
- package/schemas/work-state.schema.json +1 -0
- package/src/cli.js +21 -2
- package/src/commands/doctor.js +22 -0
- package/src/commands/migrate-protocol.js +18 -0
- package/src/commands/protocol-info.js +16 -0
- package/src/commands/run-check.js +2 -0
- package/src/commands/task-create.js +3 -2
- package/src/commands/task-lock-status.js +29 -0
- package/src/commands/task-show.js +3 -3
- package/src/commands/task-unlock.js +8 -6
- package/src/core/artifacts.js +17 -4
- package/src/core/cli-command-definitions.js +44 -0
- package/src/core/completion-artifacts.js +15 -3
- package/src/core/completion.js +15 -3
- package/src/core/diagnosis.js +15 -11
- package/src/core/error-codes.js +18 -0
- package/src/core/events.js +109 -8
- package/src/core/execution.js +73 -9
- package/src/core/filesystem.js +20 -2
- package/src/core/phase.js +8 -2
- package/src/core/protocol-info.js +41 -0
- package/src/core/protocol-migration.js +59 -0
- package/src/core/reconcile-closure.js +22 -4
- package/src/core/resumability.js +8 -6
- package/src/core/task-command.js +3 -3
- package/src/core/task-lock.js +40 -4
- package/src/core/task-migration.js +24 -1
- package/src/core/task-paths.js +3 -1
- package/src/core/transaction.js +259 -0
- package/src/core/work-state.js +70 -6
package/AGENT_COMPATIBILITY.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Deprecated filename
|
|
2
2
|
|
|
3
|
+
> Deprecated since package `1.2.4`; retained as a repository compatibility stub.
|
|
4
|
+
> It is not part of the public integration surface and is scheduled for removal
|
|
5
|
+
> in the next compatibility-breaking release.
|
|
6
|
+
|
|
3
7
|
ForgeLoop is vendor-neutral and does not use a supported-agent allowlist.
|
|
4
8
|
|
|
5
9
|
The canonical integration contract is:
|
package/DOCS_INDEX.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Documentation index
|
|
2
2
|
|
|
3
|
+
The machine-readable inventory is
|
|
4
|
+
[`docs/documentation-manifest.json`](./docs/documentation-manifest.json). It
|
|
5
|
+
classifies every package-shipped document, names canonical concept owners, and
|
|
6
|
+
records generated/deprecated-document metadata. Normative requirements and
|
|
7
|
+
their implementation/test mappings are in
|
|
8
|
+
[`docs/protocol-requirements.json`](./docs/protocol-requirements.json).
|
|
9
|
+
|
|
3
10
|
ForgeLoop keeps one canonical process and separates protocol behavior from
|
|
4
11
|
integration and guide context. Use this map before editing documentation.
|
|
5
12
|
|
package/EXECUTION_STATE.md
CHANGED
|
@@ -51,6 +51,14 @@ and rename it into place. The host filesystem's rename guarantee is the
|
|
|
51
51
|
atomicity boundary; no database or remote state is involved. A truncated,
|
|
52
52
|
malformed, or secret-bearing file is invalid and is never resumed silently.
|
|
53
53
|
|
|
54
|
+
Lifecycle mutations that change more than one artifact use a task transaction
|
|
55
|
+
under `.forgeloop/.txn/<transactionId>/`. The transaction records every staged
|
|
56
|
+
replacement and append. Ledger appends validate a bounded tail checkpoint and
|
|
57
|
+
stage only the new NDJSON suffix; if publication is interrupted, recovery
|
|
58
|
+
truncates that suffix to its recorded pre-append size. A stale checkpoint never
|
|
59
|
+
authorizes a new sequence number: ForgeLoop rebuilds it from the ledger before
|
|
60
|
+
continuing.
|
|
61
|
+
|
|
54
62
|
Before resuming, compare:
|
|
55
63
|
|
|
56
64
|
- the task contract fingerprint;
|
package/LOOP_ENGINEERING.md
CHANGED
|
@@ -1275,7 +1275,7 @@ to inspect first.
|
|
|
1275
1275
|
`CONTINUITY_CONTEXT_IS_NOT_EVIDENCE`: continuity may guide inspection but can
|
|
1276
1276
|
never satisfy verification coverage, publication, production readiness, or
|
|
1277
1277
|
completion. `CONTINUITY_CANNOT_GRANT_AUTHORITY`: continuity cannot authorize an
|
|
1278
|
-
installation or external action.
|
|
1278
|
+
installation or external action. <a id="FL-CONT-001"></a> **FL-CONT-001 — A receiving harness MUST reconcile**
|
|
1279
1279
|
continuity against the current work state and checkout before acting on it.
|
|
1280
1280
|
|
|
1281
1281
|
## Multi-task concurrent project state
|
package/LOOP_SYSTEM_DESIGN.md
CHANGED
|
@@ -218,6 +218,16 @@ The threat model records path, symlink, artifact, secret, stale-state,
|
|
|
218
218
|
publication, schema, dependency, and resource-limit boundaries with their
|
|
219
219
|
mitigations, residual limitations, and executable evidence.
|
|
220
220
|
|
|
221
|
+
Persistent task mutations use a task lease lock and a recoverable transaction
|
|
222
|
+
journal. State writes carry a monotonically increasing revision, while event
|
|
223
|
+
appends are serialized and hash chained. The ledger keeps a validated tail
|
|
224
|
+
checkpoint (`seq` and last hash), so a normal append stages and publishes only
|
|
225
|
+
its new NDJSON suffix; a mismatched tail forces a full checkpoint rebuild. A
|
|
226
|
+
crash during a multi-file publish leaves a journal that `doctor --fix` can roll
|
|
227
|
+
back deterministically — including truncating an interrupted ledger suffix to
|
|
228
|
+
its recorded pre-append size. It never permits a partial artifact set to be
|
|
229
|
+
presented as a completed protocol state.
|
|
230
|
+
|
|
221
231
|
### `ENG/*.md`
|
|
222
232
|
|
|
223
233
|
Nine canonical guides cover:
|
package/PROTOCOL_INTEGRATION.md
CHANGED
|
@@ -108,6 +108,36 @@ workflows that do not automatically discover one of the default files:
|
|
|
108
108
|
|
|
109
109
|
A developer or custom automation can execute ForgeLoop identically to an AI agent.
|
|
110
110
|
|
|
111
|
+
### Compatibility handshake
|
|
112
|
+
|
|
113
|
+
Before a harness creates or resumes task state, it can read the complete
|
|
114
|
+
machine-readable compatibility boundary:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
forgeloop protocol-info --json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
When a compatibility change requires persisted state conversion, inspect it
|
|
121
|
+
before writing anything:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
forgeloop migrate-protocol --to 1 --dry-run --json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`migrate-protocol` accepts only versions with an explicit migration in the
|
|
128
|
+
installed release. Unsupported targets fail without rewriting state. The
|
|
129
|
+
current protocol's only supported conversion is the receipt-backed legacy
|
|
130
|
+
singleton-layout migration; a future protocol version must add its own
|
|
131
|
+
validated migration before it can become an accepted `--to` value.
|
|
132
|
+
|
|
133
|
+
The response separates package and protocol identity. `packageVersion` is the
|
|
134
|
+
installed CLI version; `readsProtocol` and `writesProtocol` enumerate protocol
|
|
135
|
+
versions supported by this CLI; `readsSchemaVersions` and
|
|
136
|
+
`writesSchemaVersions` map every public artifact schema to its supported
|
|
137
|
+
versions. A harness must not infer compatibility from the package version
|
|
138
|
+
alone, and it must fail closed when its required protocol or schema version is
|
|
139
|
+
absent from the relevant list.
|
|
140
|
+
|
|
111
141
|
## CLI resolution policy
|
|
112
142
|
|
|
113
143
|
Lifecycle-owned protocol state must be managed through the project-local ForgeLoop CLI:
|
package/README.md
CHANGED
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
<img src="./docs/assets/eng_readme_forgeloop.png" alt="ForgeLoop — Loop Engineering for AI Agents" width="100%">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
+
[](https://github.com/cassiomc1/forgeloop/actions/workflows/codeql.yml)
|
|
8
|
+
[](https://github.com/cassiomc1/forgeloop/actions/workflows/dependency-review.yml)
|
|
7
9
|
[](https://github.com/cassiomc1/forgeloop/actions/workflows/docs-quality.yml)
|
|
10
|
+
[](https://github.com/cassiomc1/forgeloop/actions/workflows/forgeloop-audit.yml)
|
|
11
|
+
[](https://github.com/cassiomc1/forgeloop/actions/workflows/npm-publish.yml)
|
|
12
|
+
[](https://github.com/cassiomc1/forgeloop/actions/workflows/package-smoke.yml)
|
|
13
|
+
[](https://github.com/cassiomc1/forgeloop/actions/workflows/release-notes.yml)
|
|
8
14
|
|
|
9
15
|
ForgeLoop is a portable, vendor-neutral protocol for AI-assisted development
|
|
10
16
|
and developer workflows. It turns an outcome into a contract, deterministic
|
|
@@ -52,6 +58,45 @@ frontmatter. Repository validators keep the catalog and metadata synchronized.
|
|
|
52
58
|
|
|
53
59
|
## Quickstart
|
|
54
60
|
|
|
61
|
+
### Demonstração em 60 segundos
|
|
62
|
+
|
|
63
|
+
Em um diretório descartável, inicialize o kit e crie uma tarefa isolada. O
|
|
64
|
+
resultado é determinístico e pode ser inspecionado por qualquer harness
|
|
65
|
+
compatível:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx @cassiomc1/forgeloop init
|
|
69
|
+
forgeloop task-create --task demo --claim src --json
|
|
70
|
+
forgeloop route --task demo --work clean-code --json
|
|
71
|
+
forgeloop preflight --task demo --json
|
|
72
|
+
forgeloop next --task demo --json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
O último comando informa a ação segura seguinte; ele não executa código nem
|
|
76
|
+
agenda agentes.
|
|
77
|
+
|
|
78
|
+
Antes de um harness criar ou retomar uma tarefa, ele pode confirmar a
|
|
79
|
+
compatibilidade pública sem depender de detalhes internos:
|
|
80
|
+
|
|
81
|
+
<!-- FORGELOOP EXAMPLE: readme:compatibility | exit=0 | json.protocolVersion=1 -->
|
|
82
|
+
```bash
|
|
83
|
+
forgeloop protocol-info --json
|
|
84
|
+
```
|
|
85
|
+
<!-- END FORGELOOP EXAMPLE -->
|
|
86
|
+
|
|
87
|
+
### Responsabilidades
|
|
88
|
+
|
|
89
|
+
| Responsabilidade | ForgeLoop | Harness ou desenvolvedor |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| Validar contrato e rotas | Sim | Fornece intenção e sinais |
|
|
92
|
+
| Implementar código | Não | Sim |
|
|
93
|
+
| Registrar proveniência de comando | Sim, com `run-check` | Fornece comando e ambiente |
|
|
94
|
+
| Validar conclusão | Sim | Fornece trabalho e evidência reais |
|
|
95
|
+
| Agendar agentes ou inferência LLM | Não | Externo ao protocolo |
|
|
96
|
+
|
|
97
|
+
Para uma troca concreta entre ferramentas, veja a
|
|
98
|
+
[continuidade entre harnesses](./docs/CROSS_HARNESS_CONTINUITY.md).
|
|
99
|
+
|
|
55
100
|
From a published package, initialize a target project with:
|
|
56
101
|
|
|
57
102
|
```bash
|
|
@@ -240,6 +285,9 @@ repository policy allows only ESLint, c8, and Mermaid CLI as development
|
|
|
240
285
|
dependencies; `npm run dependency:policy` fails if runtime or unapproved
|
|
241
286
|
dependencies appear.
|
|
242
287
|
|
|
288
|
+
Para reportar vulnerabilidades ou contribuir com alterações, consulte
|
|
289
|
+
[`SECURITY.md`](./SECURITY.md) e [`CONTRIBUTING.md`](./CONTRIBUTING.md).
|
|
290
|
+
|
|
243
291
|
## Autonomous blind-run isolation
|
|
244
292
|
|
|
245
293
|
The repository does not claim a live blind conformance result for an external
|
package/THREAT_MODEL.md
CHANGED
|
@@ -17,6 +17,8 @@ remaining trust boundaries and their executable evidence.
|
|
|
17
17
|
| Malicious work-state | Resumes stale, secret-bearing, or invalid work | `.forgeloop/work-state.json` | Schema/semantic checks, version checks, transition checks, contract/HEAD/artifact freshness, secret scan, size/depth bounds | Freshness cannot prove that an external process did not alter a file immediately afterward | `tests/work-state.test.js`, `tests/checkpoint-freshness.test.js`, `tests/security-limits.test.js` |
|
|
18
18
|
| Forged preparation | Makes an agent's prose claim look like a completed preflight | Contract, route, gate, and preflight artifacts | Canonical SHA-256 fingerprints, guide-declared gate requirements, stale-artifact checks, and `E_*` failures | The CLI cannot stop a separate process from writing project files before preflight | `tests/protocol-artifacts.test.js`, `tests/preflight.test.js` |
|
|
19
19
|
| Chronology rewrite | Hides execution before route, gates, or verification | `.forgeloop/events.ndjson` | Append-only local ledger, sequence numbers, hash chaining, and chronology validation without prompts or hidden reasoning | A privileged process can still replace the ledger after validation | `tests/lifecycle.test.js` |
|
|
20
|
+
| Concurrent protocol mutation | Two writers read the same state or ledger tail and silently overwrite each other | Task state, task event ledger, and transaction journal | Mutations acquire a lease-bearing task lock, stage writes in `.forgeloop/.txn/`, preserve a recovery manifest, and publish only after the callback completes; state mutators use an expected revision, while ledger appends validate a tail checkpoint and stage only a synchronized suffix | The filesystem does not provide a multi-file atomic commit primitive; a process killed during append is recovered by truncating to the journaled pre-append size rather than treated as complete | `tests/state-revision.test.js`, `tests/concurrent-ledger.test.js`, `tests/scale-ledger.test.js`, `tests/transaction.test.js` |
|
|
21
|
+
| Stale lock theft | A live process loses exclusive ownership because another process removes its lock | `.forgeloop/locks/<taskKey>.lock` | Locks record hostname, owner instance ID, heartbeat, and lease; inspection classifies `LIVE`, `STALE`, or `UNKNOWN`; ordinary recovery releases only an expired lease and `--force` is explicit | A malicious or separately privileged actor can still delete local locks | `tests/task-cli.test.js`, `tests/task-foundation.test.js` |
|
|
20
22
|
| Lifecycle artifact repair | Direct state or receipt edits fabricate a legal recovery or terminal phase | Work state, receipt, evidence checks, and event ledger | New verification cycles record phase events and fingerprints; validators reject state/ledger divergence and future lifecycle evidence | Local artifacts are detection-oriented, not cryptographically tamper-proof against a privileged process rewriting every linked artifact | `tests/lifecycle-evidence-recovery.test.js`, `tests/completion-ergonomics.test.js` |
|
|
21
23
|
| Unsupported profile fact | Turns an agent decision into a durable user fact | `PROJECT_PROFILE.md` and `.forgeloop/sources.json` | Source IDs, source-kind validation, unknown-reference rejection, and explicit misclassification failures | Arbitrary Markdown semantics still require a human or host-specific parser | `tests/profile-provenance.test.js`, `src/core/profile.js` |
|
|
22
24
|
| Weak verification | Treats a vague or inferred claim as observed evidence | Receipt checks and coverage | Versioned check schema, contradictory-status rejection, observed-evidence requirements, and coverage matrix | Evidence remains local and declarative; it is not a remote attestation service | `tests/evidence-coverage.test.js`, `tests/completion.test.js` |
|
|
@@ -53,7 +55,7 @@ remaining trust boundaries and their executable evidence.
|
|
|
53
55
|
| Lock regeneration or subdigest tampering | An actor modifies rules or baseline, omits subdigests, or regenerates `policy.lock` to hide tampering | Effective policy lock verification (`verifyPolicyLock`) | Lock derives deterministically from effective rules + baseline. Schema-invalid lock artifacts (malformed JSON or missing required fields such as `rulesDigest`/`baselineDigest`) fail closed with `E_POLICY_INVALID`; schema-valid locks whose semantic digest components (`algorithm`, `digest`, `rulesDigest`, `baselineDigest`) no longer match effective policy state fail with `E_POLICY_LOCK_MISMATCH` before any relocking. Changing only `capturedAt` does not change semantic identity | Explicit update commands (`policy-discover --write`, `baseline`) update lock after authorization | `tests/policy-hardening.test.js` |
|
|
54
56
|
| Baseline re-record bypass | An actor uses `baseline --record` during an active task to convert newly introduced violations into tolerated debt | Active task baseline protection in `runBaseline` | `baseline --record` is rejected during active policy-bound tasks with `E_BASELINE_RECORD_DURING_ACTIVE_TASK`; only monotonic `--update` is permitted | Explicit `--policy-reset-authorized` flag required for intentional operator resets | `tests/policy-hardening.test.js` |
|
|
55
57
|
| Legacy snapshot semantic confusion | A legacy task snapshot lacking baseline state is assumed to have empty baseline, creating false `WEAKEN` drift | Semantic baseline snapshotting in `policy-snapshot.json` | Snapshots retain full semantic baseline entries; snapshots lacking baseline state classify drift as `UNKNOWN` rather than inventing state | Modern tasks retain semantic baseline entries for exact diff | `tests/policy-hardening.test.js` |
|
|
56
|
-
| Cross-task state confusion | Concurrent processes or alternative harnesses mutate or read the wrong task's state in a multi-task workspace | Task-scoped isolation in `.forgeloop/task-state/<taskKey>/` | Deterministic SHA-256 task directory namespacing, explicit `--task` / `FORGELOOP_TASK` selectors, file-level
|
|
58
|
+
| Cross-task state confusion | Concurrent processes or alternative harnesses mutate or read the wrong task's state in a multi-task workspace | Task-scoped isolation in `.forgeloop/task-state/<taskKey>/` | Deterministic SHA-256 task directory namespacing, explicit `--task` / `FORGELOOP_TASK` selectors, separate file-level lease locks under `.forgeloop/locks/`, and claim overlap detection in `task-create` | Tasks must declare non-overlapping write claims or operate in isolated worktrees | `tests/task-namespace.test.js`, `tests/task-scope.test.js` |
|
|
57
59
|
| Modern namespace descriptor deletion | Corruption or an attacker removes `task.json` from a modern task namespace (leaving contract/work-state/receipt/events), the resolver ignores the namespace, and stale legacy singleton state becomes authoritative | Descriptor boundary between modern task namespaces and the legacy singleton | Descriptor-less 64-hex directories are classified by contents: directories containing modern task artifacts (or empty directories) fail closed with `E_TASK_DESCRIPTOR_INVALID`; only directories containing exclusively the explicitly recognized legacy-incidental artifact (`policy-snapshot.json`) are ignored; `resolveTaskContext` fails closed when all namespaces are corrupt | A separately privileged process can rewrite task-state directories after validation | `tests/validate-receipt-task.test.js` |
|
|
58
60
|
|
|
59
61
|
## Boundary rules
|
|
@@ -287,6 +287,7 @@ The canonical, authoritative lifecycle work state. Represents current checkpoint
|
|
|
287
287
|
- `failures` *(array<object>, required)*
|
|
288
288
|
- `blockers` *(array<object>, required)*
|
|
289
289
|
- `lastUpdated` *(string, required, minLength: 1)*
|
|
290
|
+
- `revision` *(integer, optional, minimum: 0)*
|
|
290
291
|
- `previousPhase` *(string, optional)*
|
|
291
292
|
- `diagnosedHypothesis` *(string, optional, minLength: 1)*
|
|
292
293
|
- `verificationEvidence` *(array<object>, optional)*
|
|
@@ -421,6 +422,16 @@ Attested command execution provenance artifact generated by `forgeloop run-check
|
|
|
421
422
|
- `finishedAt` *(string, required, minLength: 1)*
|
|
422
423
|
- `status` *(string, required, enum: `passed`, `failed`)*
|
|
423
424
|
- `exitCode` *(integer or null, required)*
|
|
425
|
+
- `durationMs` *(integer, optional, minimum: 0)*
|
|
426
|
+
- `termination` *(string, optional, enum: `exit`, `signal`, `timeout`, `spawn-error`)*
|
|
427
|
+
- `signal` *(string or null, optional)*
|
|
428
|
+
- `stdoutSha256` *(string, optional, pattern: `^[a-f0-9]{64}$`)*
|
|
429
|
+
- `stderrSha256` *(string, optional, pattern: `^[a-f0-9]{64}$`)*
|
|
430
|
+
- `stdoutBytes` *(integer, optional, minimum: 0)*
|
|
431
|
+
- `stderrBytes` *(integer, optional, minimum: 0)*
|
|
432
|
+
- `outputTruncated` *(boolean, optional)*
|
|
433
|
+
- `timeoutMs` *(integer, optional, minimum: 1)*
|
|
434
|
+
- `terminationGraceMs` *(integer, optional, minimum: 1)*
|
|
424
435
|
|
|
425
436
|
<!-- END FORGELOOP GENERATED: schema:execution -->
|
|
426
437
|
|
package/docs/CLI_REFERENCE.md
CHANGED
|
@@ -39,9 +39,9 @@ ForgeLoop uses a definition-driven command-line parser:
|
|
|
39
39
|
|
|
40
40
|
| Category | Commands |
|
|
41
41
|
| --- | --- |
|
|
42
|
-
| **
|
|
43
|
-
| **
|
|
44
|
-
| **Lifecycle & State** | [`activate`](#activate), [`route`](#route), [`preflight`](#preflight), [`advance`](#advance), [`next`](#next), [`record-diagnosis`](#record-diagnosis), [`record-decision-criterion`](#record-decision-criterion), [`complete`](#complete), [`clear-state`](#clear-state), [`reconcile-closure`](#reconcile-closure), [`task-create`](#task-create), [`task-list`](#task-list), [`task-show`](#task-show), [`task-scope`](#task-scope) |
|
|
42
|
+
| **Inspection & Diagnostics** | [`protocol-info`](#protocol-info), [`doctor`](#doctor), [`progress`](#progress), [`profile-interview`](#profile-interview), [`inspect`](#inspect), [`status`](#status), [`validate-state`](#validate-state), [`validate-protocol`](#validate-protocol) |
|
|
43
|
+
| **Setup & Maintenance** | [`init`](#init), [`update`](#update), [`task-migrate`](#task-migrate), [`migrate-protocol`](#migrate-protocol), [`task-unlock`](#task-unlock) |
|
|
44
|
+
| **Lifecycle & State** | [`activate`](#activate), [`route`](#route), [`preflight`](#preflight), [`advance`](#advance), [`next`](#next), [`record-diagnosis`](#record-diagnosis), [`record-decision-criterion`](#record-decision-criterion), [`complete`](#complete), [`clear-state`](#clear-state), [`reconcile-closure`](#reconcile-closure), [`task-create`](#task-create), [`task-list`](#task-list), [`task-show`](#task-show), [`task-lock-status`](#task-lock-status), [`task-scope`](#task-scope) |
|
|
45
45
|
| **Cross-Harness Continuity** | [`continuity`](#continuity), [`record-continuity`](#record-continuity), [`reconcile-continuity`](#reconcile-continuity), [`clear-continuity`](#clear-continuity) |
|
|
46
46
|
| **Verification & Completion** | [`prepare-completion`](#prepare-completion), [`run-check`](#run-check), [`record-check`](#record-check), [`record-terminal-result`](#record-terminal-result), [`audit`](#audit), [`report`](#report), [`validate-receipt`](#validate-receipt) |
|
|
47
47
|
| **Policy & Auditing** | [`policy`](#policy), [`policy-discover`](#policy-discover), [`policy-status`](#policy-status), [`policy-diff`](#policy-diff), [`rule-verify`](#rule-verify), [`baseline`](#baseline), [`bundle`](#bundle) |
|
|
@@ -52,6 +52,30 @@ ForgeLoop uses a definition-driven command-line parser:
|
|
|
52
52
|
|
|
53
53
|
## 1. Setup & Maintenance
|
|
54
54
|
|
|
55
|
+
### `protocol-info`
|
|
56
|
+
|
|
57
|
+
Reports the public compatibility handshake required by external ForgeLoop harnesses.
|
|
58
|
+
|
|
59
|
+
- **Purpose**: Publishes protocol/schema versioning, lifecycle metadata, command metadata, guide registry, and the documented error registry.
|
|
60
|
+
- **When to use**: Before a harness creates or resumes a ForgeLoop task, and when verifying compatibility without reading internal source.
|
|
61
|
+
- **Mutation**: Read-only.
|
|
62
|
+
- **Options**:
|
|
63
|
+
|
|
64
|
+
<!-- BEGIN FORGELOOP GENERATED: cli:protocol-info:options -->
|
|
65
|
+
|
|
66
|
+
- `--path <directory>`: target project directory (default: current directory)
|
|
67
|
+
- `--json`: emit complete machine-readable protocol metadata
|
|
68
|
+
|
|
69
|
+
<!-- END FORGELOOP GENERATED: cli:protocol-info:options -->
|
|
70
|
+
|
|
71
|
+
- **Example**:
|
|
72
|
+
|
|
73
|
+
<!-- FORGELOOP EXAMPLE: cli-reference:protocol-info | exit=0 | json.commands.0.name=protocol-info -->
|
|
74
|
+
```bash
|
|
75
|
+
forgeloop protocol-info --json
|
|
76
|
+
```
|
|
77
|
+
<!-- END FORGELOOP EXAMPLE -->
|
|
78
|
+
|
|
55
79
|
### `init`
|
|
56
80
|
|
|
57
81
|
Initializes ForgeLoop in a target repository.
|
|
@@ -407,6 +431,7 @@ Executes a verification command with ForgeLoop-attested provenance.
|
|
|
407
431
|
- `--id <id>`: stable check identifier
|
|
408
432
|
- `--requirement <id>`: completion requirement covered by the check
|
|
409
433
|
- `--details <json>`: additional structured check details
|
|
434
|
+
- `--timeout-ms <number>`: maximum command duration before termination
|
|
410
435
|
- `-- <argv...>`: exact command argv to classify, execute, and attest
|
|
411
436
|
- `--json`: emit structured output as JSON
|
|
412
437
|
|
|
@@ -1139,6 +1164,27 @@ Displays details of a specific task by ID or storage key.
|
|
|
1139
1164
|
forgeloop task-show --task task-001 --json
|
|
1140
1165
|
```
|
|
1141
1166
|
|
|
1167
|
+
### `task-lock-status`
|
|
1168
|
+
|
|
1169
|
+
Reports the lock owner and lease-based staleness classification for a specific task without mutating it.
|
|
1170
|
+
|
|
1171
|
+
- **Mutation**: Read-only.
|
|
1172
|
+
- **Options**:
|
|
1173
|
+
|
|
1174
|
+
<!-- BEGIN FORGELOOP GENERATED: cli:task-lock-status:options -->
|
|
1175
|
+
|
|
1176
|
+
- `--path <directory>`: target project directory (default: current directory)
|
|
1177
|
+
- `--task <id>`: task ID to operate on (when omitted, resolved from context or single active task)
|
|
1178
|
+
- `--json`: emit structured output as JSON
|
|
1179
|
+
|
|
1180
|
+
<!-- END FORGELOOP GENERATED: cli:task-lock-status:options -->
|
|
1181
|
+
|
|
1182
|
+
- **Example**:
|
|
1183
|
+
|
|
1184
|
+
```bash
|
|
1185
|
+
forgeloop task-lock-status --task task-001 --json
|
|
1186
|
+
```
|
|
1187
|
+
|
|
1142
1188
|
### `task-scope`
|
|
1143
1189
|
|
|
1144
1190
|
Updates or inspects write claims for a task.
|
|
@@ -1184,6 +1230,37 @@ Migrates a legacy 1.0 single-task `.forgeloop/` layout into a namespaced task di
|
|
|
1184
1230
|
forgeloop task-migrate --json
|
|
1185
1231
|
```
|
|
1186
1232
|
|
|
1233
|
+
### `migrate-protocol`
|
|
1234
|
+
|
|
1235
|
+
Plans or applies an explicitly supported persisted-state migration to a target
|
|
1236
|
+
protocol version.
|
|
1237
|
+
|
|
1238
|
+
- **Purpose**: Provides a fail-closed compatibility migration surface. In the
|
|
1239
|
+
current release, target protocol `1` either needs no change or converts a
|
|
1240
|
+
detected legacy singleton layout through the verified `task-migrate` flow.
|
|
1241
|
+
- **When to use**: Before upgrading persisted ForgeLoop state when a release
|
|
1242
|
+
documents a new protocol migration. Run the dry-run first and retain the
|
|
1243
|
+
resulting migration receipt after applying a legacy conversion.
|
|
1244
|
+
- **Mutation**: Does not write with `--dry-run`. A supported legacy conversion
|
|
1245
|
+
writes the namespaced task state and its `migration-receipt.json` before
|
|
1246
|
+
removing legacy artifacts.
|
|
1247
|
+
- **Options**:
|
|
1248
|
+
|
|
1249
|
+
<!-- BEGIN FORGELOOP GENERATED: cli:migrate-protocol:options -->
|
|
1250
|
+
|
|
1251
|
+
- `--path <directory>`: target project directory (default: current directory)
|
|
1252
|
+
- `--to <protocolVersion>`: target supported protocol version
|
|
1253
|
+
- `--dry-run`: show migration actions without writing or deleting artifacts
|
|
1254
|
+
- `--json`: emit structured migration result as JSON
|
|
1255
|
+
|
|
1256
|
+
<!-- END FORGELOOP GENERATED: cli:migrate-protocol:options -->
|
|
1257
|
+
|
|
1258
|
+
- **Example**:
|
|
1259
|
+
|
|
1260
|
+
```bash
|
|
1261
|
+
forgeloop migrate-protocol --to 1 --dry-run --json
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1187
1264
|
### `task-unlock`
|
|
1188
1265
|
|
|
1189
1266
|
Forces the release of a stale task lock.
|
|
@@ -1197,6 +1274,7 @@ Forces the release of a stale task lock.
|
|
|
1197
1274
|
- `--path <directory>`: target project directory (default: current directory)
|
|
1198
1275
|
- `--task <id>`: task ID to operate on (when omitted, resolved from context or single active task)
|
|
1199
1276
|
- `--force`: force release of an orphaned task lock
|
|
1277
|
+
- `--stale-only`: release only a lock whose lease is expired
|
|
1200
1278
|
- `--json`: emit structured output as JSON
|
|
1201
1279
|
|
|
1202
1280
|
<!-- END FORGELOOP GENERATED: cli:task-unlock:options -->
|
|
@@ -29,6 +29,15 @@ Switching between execution environments (for example Codex $\rightarrow$ Claude
|
|
|
29
29
|
|
|
30
30
|
When a new harness starts in a repository where an active task exists, it must discover the existing task, reconcile continuity when present, inspect the checkout, and proceed from the recorded state rather than overwriting the contract.
|
|
31
31
|
|
|
32
|
+
Before it touches task state, a harness can verify the public compatibility
|
|
33
|
+
handshake it will use for the handoff:
|
|
34
|
+
|
|
35
|
+
<!-- FORGELOOP EXAMPLE: cross-harness:handshake | exit=0 | json.lifecycle.phases.0=RECEIVED -->
|
|
36
|
+
```bash
|
|
37
|
+
forgeloop protocol-info --json
|
|
38
|
+
```
|
|
39
|
+
<!-- END FORGELOOP EXAMPLE -->
|
|
40
|
+
|
|
32
41
|
Key continuity invariants:
|
|
33
42
|
|
|
34
43
|
- **Continuity is optional**: A missing `continuity.json` file does not invalidate an otherwise resumable task.
|
|
@@ -133,9 +142,11 @@ forgeloop status --json
|
|
|
133
142
|
|
|
134
143
|
Or with explicit flag:
|
|
135
144
|
|
|
145
|
+
<!-- FORGELOOP EXAMPLE: cross-harness:status | fixture=task:auth-feature | exit=0 | json.taskId=auth-feature -->
|
|
136
146
|
```bash
|
|
137
147
|
forgeloop status --task auth-feature --json
|
|
138
148
|
```
|
|
149
|
+
<!-- END FORGELOOP EXAMPLE -->
|
|
139
150
|
|
|
140
151
|
Verify that the task exists and observe the current lifecycle phase (e.g. `EXECUTING` or `VERIFYING`). If multiple tasks exist and no selector is provided, ForgeLoop returns `E_TASK_AMBIGUOUS`.
|
|
141
152
|
|
|
@@ -123,6 +123,21 @@ When writing documentation, use precise terms:
|
|
|
123
123
|
|
|
124
124
|
Avoid ambiguous phrases like *"should generally"* or *"usually"* for behaviors that are strictly enforced by the validator.
|
|
125
125
|
|
|
126
|
+
### Stable requirement IDs
|
|
127
|
+
|
|
128
|
+
Every protocol-level `MUST` or `MUST NOT` has a stable `FL-<AREA>-<NNN>`
|
|
129
|
+
anchor and an entry in [`protocol-requirements.json`](./protocol-requirements.json).
|
|
130
|
+
Each map entry names its normative source, implementation validator, and at
|
|
131
|
+
least one executable test. `npm run docs:check` rejects an unmapped normative
|
|
132
|
+
requirement, an unused mapping, or a missing implementation/test target.
|
|
133
|
+
|
|
134
|
+
### Documentation impact classification
|
|
135
|
+
|
|
136
|
+
Classify each documentation-impacting change as one or more of: `NONE`,
|
|
137
|
+
`REFERENCE_ONLY`, `OPERATIONAL`, `NORMATIVE`, `SCHEMA_COMPATIBILITY`,
|
|
138
|
+
`MIGRATION`, or `SECURITY`. Changes that are normative, compatibility,
|
|
139
|
+
migration, or security-sensitive require `npm run docs:check` before merge.
|
|
140
|
+
|
|
126
141
|
### Multi-Task Layout Rules
|
|
127
142
|
|
|
128
143
|
- Canonical task-scoped paths are defined in `src/core/task-paths.js` under `.forgeloop/task-state/<taskKey>/`.
|
|
@@ -196,3 +211,5 @@ For documentation-impacting changes, verify each item before merging:
|
|
|
196
211
|
- [ ] Did package-shipped documentation change?
|
|
197
212
|
- [ ] Were generated reference docs updated (`npm run docs:generate`)?
|
|
198
213
|
- [ ] Did documentation conformance CI pass (`npm run docs:check`)?
|
|
214
|
+
- [ ] If normative language changed, are stable IDs and mappings current?
|
|
215
|
+
- [ ] Is the documentation impact classification recorded in the PR?
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -39,6 +39,15 @@ Core mental model:
|
|
|
39
39
|
|
|
40
40
|
In your project repository:
|
|
41
41
|
|
|
42
|
+
Confirm the installed CLI exposes the compatible protocol before creating
|
|
43
|
+
state. This is read-only and safe to run in a fresh project directory.
|
|
44
|
+
|
|
45
|
+
<!-- FORGELOOP EXAMPLE: getting-started:compatibility | exit=0 | json.compatibility.schemaVersion=1 -->
|
|
46
|
+
```bash
|
|
47
|
+
forgeloop protocol-info --json
|
|
48
|
+
```
|
|
49
|
+
<!-- END FORGELOOP EXAMPLE -->
|
|
50
|
+
|
|
42
51
|
```bash
|
|
43
52
|
# Initialize ForgeLoop kit and discovery shims
|
|
44
53
|
npx @cassiomc1/forgeloop init
|
package/docs/RECIPES.md
CHANGED
|
@@ -25,11 +25,15 @@ Concise, copy-paste friendly recipes for common ForgeLoop tasks.
|
|
|
25
25
|
|
|
26
26
|
### Recipe 1 — Start a New Task
|
|
27
27
|
|
|
28
|
+
<!-- FORGELOOP EXAMPLE: recipes:create-task | exit=0 | json.taskId=task-001 -->
|
|
28
29
|
```bash
|
|
29
|
-
# 1. Create a task with explicit claims
|
|
30
30
|
forgeloop task-create --task task-001 --claim src --claim tests --json
|
|
31
|
+
```
|
|
32
|
+
<!-- END FORGELOOP EXAMPLE -->
|
|
31
33
|
|
|
34
|
+
```bash
|
|
32
35
|
# 2. Discover task state path and author contract under .forgeloop/task-state/<taskKey>/contract.json
|
|
36
|
+
|
|
33
37
|
forgeloop task-show --task task-001 --json
|
|
34
38
|
|
|
35
39
|
# 3. Route engineering guides
|