@cassiomc1/forgeloop 0.1.13 → 0.1.15

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.
@@ -1,2 +1,3 @@
1
1
  # Local resumable task state is untrusted, target-specific data.
2
2
  work-state.json
3
+ executions/
@@ -52,6 +52,7 @@ the supported ForgeLoop lifecycle commands or canonical ForgeLoop APIs:
52
52
  - `.forgeloop/work-state.json`
53
53
  - `.forgeloop/events.ndjson`
54
54
  - `.forgeloop/execution-receipt.json`
55
+ - `.forgeloop/executions/<executionId>.json`
55
56
  - completion recovery metadata
56
57
  - canonical check/evidence state
57
58
  - terminal-result lifecycle state
@@ -108,6 +109,60 @@ rules permit it.
108
109
  A missing checker must never be converted into environmental mutation merely
109
110
  to make verification pass.
110
111
 
112
+ ### Verification command resolution modes and validator enforcement
113
+
114
+ Every verification command path is classified by resolution mode:
115
+
116
+ | Mode | Examples | May install software | Authority required |
117
+ | --- | --- | --- | --- |
118
+ | `LOCAL_EXECUTABLE` | `node scripts/test.js`, `python3 -m unittest`, `./bin/check` | No | No |
119
+ | `LOCAL_PACKAGE_BINARY` | `./node_modules/.bin/tool`, `npm test`, `pnpm test`, `yarn test` | No | No |
120
+ | `NON_INSTALLING_RESOLUTION` | `npx --no-install tool`, `npx --no tool` | No | No |
121
+ | `INSTALL_CAPABLE_RESOLUTION` | `npx tool`, `npm exec tool`, `npm x tool`, `pnpm dlx tool`, `yarn dlx tool`, `bunx tool`, `uvx tool`, `pipx run tool` | Yes | Yes (`E_INSTALLATION_AUTHORITY_REQUIRED`) |
122
+ | `EXPLICIT_INSTALLATION` | `npm install tool`, `pnpm add tool`, `pip install tool`, `cargo install tool` | Yes | Yes (`E_INSTALLATION_AUTHORITY_REQUIRED`) |
123
+
124
+ **Validator-enforced rule**: Any verification command executed via an installation-capable or explicit-installation resolution mode without a valid canonical installation authority grant is rejected by `record-check`, `audit`, and `complete` with error code `E_INSTALLATION_AUTHORITY_REQUIRED`, `E_AUTHORITY_INVALID`, `E_AUTHORITY_SCOPE_MISMATCH`, or `E_AUTHORITY_UNTRUSTED_SOURCE` and cannot contribute to `VALID` completion.
125
+
126
+ Recognized command dispatchers (such as `npm test`, `npm start`, `npm stop`, `npm restart`, `npm run <script>`, `npm run-script <script>`, `npm rum <script>`, `npm urn <script>`) are classified by their effective package resolution behavior across recognized lifecycle scripts before process launch. npm invocation parsing recognizes options (e.g. `--silent`, `--loglevel=error`) before the subcommand. Recognized npm-script dispatch is resolved recursively before process launch. `npm restart` uses npm's restart-specific lifecycle semantics (`prerestart`, `prestop`, `stop`, `poststop`, `prestart`, `start`, `poststart`, `postrestart` when `restart` is absent; `prerestart`, `restart`, `postrestart` when `restart` is present) rather than generic pre/main/post handling. ForgeLoop fails closed (`mayInstall: true`) when recursive npm-script resolution encounters a cycle or exceeds its maximum resolution depth (16). ForgeLoop does not resolve npm workspace selection in `run-check` for `0.1.15`. npm script executions using `--workspace`, `-w`, `--workspaces`, or `--ws` fail closed (`E_COMMAND_RESOLUTION_AMBIGUOUS`) because the effective `package.json` execution context may differ from the current ForgeLoop target. Run ForgeLoop against the selected workspace directory directly instead. If any nested lifecycle script invokes an installation-capable command (such as `npx`, `npm exec`, or `pnpm dlx`), the execution is elevated to `INSTALL_CAPABLE_RESOLUTION` and blocked before launch without authority.
127
+
128
+ **npm Classification Model**: npm classification is semantic and fail-closed. Unknown npm commands are not assumed safe. The classifier specifically identifies install-capable families including: `exec`/`x`, `install` aliases, `ci` aliases, `install-test` families, `install-ci-test` families, `update` aliases, `audit fix`, and conditional `init`/`create`/`innit` invocations. Unknown or ambiguous semantics fail closed (`E_COMMAND_RESOLUTION_AMBIGUOUS`).
129
+
130
+ Use `forgeloop run-check --id <id> --requirement <requirement> -- <argv>` for
131
+ observed command evidence. ForgeLoop preserves the exact argv vector, target
132
+ cwd, resolution classification, timestamps, exit status, and task/check
133
+ binding in `.forgeloop/executions/<executionId>.json` before recording the
134
+ check. Resolution is classified before process launch; install-capable
135
+ resolution is rejected without a valid host-attested authority, while
136
+ `npx --no-install` remains a non-installing path and may fail honestly when a
137
+ tool is absent. `run-check` launches the supplied argv without a shell.
138
+
139
+ `forgeloop record-check` is serialization-only. Its `--command` value is
140
+ metadata and is never executed. A `kind: command`, `evidenceKind: OBSERVED`
141
+ check must carry `provenance: FORGELOOP_EXECUTED` and a valid `executionRef`;
142
+ manual or actor-reported observations must use an explicit non-command kind or
143
+ provenance and must not be upgraded to command execution evidence. Completion,
144
+ audit, protocol validation, and bundles revalidate the referenced artifact and
145
+ its task, check, requirement, cycle, cwd, status, and exit-code binding.
146
+
147
+ Authority cannot be self-issued by the actor consuming it. Boolean fields inside verification evidence (such as `installationAuthorized: true`) are not sufficient proof of installation authority. Installation authority must be established via a canonical authority grant supplied by a host/operator trust boundary and referenced via `installationAuthorityRef`.
148
+
149
+ The runtime authority context has two modes:
150
+
151
+ - `NONE` is the default for the actor-facing standalone CLI. `FORGELOOP_AUTHORITY_FILE` and `FORGELOOP_AUTHORITY_DIR` may select candidate source metadata for compatibility and diagnostics, but they do not make a source trusted. An environment-selected source is rejected with `E_AUTHORITY_UNTRUSTED_SOURCE` when it is used for an installation-capable verification.
152
+ - `HOST_ATTESTED` is an internal integration context supplied by a host-owned wrapper, embedded API, or equivalent boundary. It may select a trusted authority file, directory, or in-memory provider only when the actor cannot replace that context at command invocation time. The CLI exposes no flag that promotes a source to `HOST_ATTESTED`.
153
+
154
+ External path is not equivalent to external authority ownership. The host-attested source must still resolve outside the actor-writable target, and a project-local `.forgeloop/authorities/` artifact remains an untrusted reference, cache, diagnostic, or mirror by default. A local claim such as `source: operator` is not proof of operator authority.
155
+
156
+ ForgeLoop validates authority semantics, while the host defines the trust boundary. If the host grants the actor write access to the configured attested source, the host boundary is compromised and ForgeLoop cannot distinguish operator authority from actor fabrication without a stronger external trust anchor.
157
+
158
+ ### Stale receipt recovery invariant
159
+
160
+ Every recovery action returned by `forgeloop next` must be executable from the state that produced it. When work state changes legitimately after preparing a completion receipt, `forgeloop prepare-completion` refreshes the receipt and re-binds it to current state and changed paths without requiring manual deletion of `.forgeloop/execution-receipt.json`.
161
+
162
+ ### Conformance profile escalation policy
163
+
164
+ A run started in Standard conformance must not be silently escalated to Strict after validator-backed completion. Strict validation is a separate conformance profile. If Strict revalidation is performed after Standard `COMPLETE`, it is treated as a distinct revalidation cycle and does not retroactively invalidate a valid Standard result.
165
+
111
166
  ## Blocking vs Non-Blocking Decisions
112
167
 
113
168
  Classify every unresolved decision before deciding whether to ask the user.
@@ -476,7 +531,7 @@ prepare-completion
476
531
 
477
532
  run applicable project checks
478
533
 
479
- record observed results with record-check
534
+ run commands with run-check; record manual observations with record-check
480
535
  ↓ forgeloop next
481
536
  advance --to REVIEWING
482
537
  ↓ forgeloop next
@@ -491,10 +546,11 @@ subsequent `record-check` operations; completion remains invalid until required
491
546
  observed evidence, review state, chronology, and validator requirements are
492
547
  satisfied.
493
548
 
494
- The host agent runs applicable checks after the receipt exists, records their
495
- observed results with `record-check`, and queries `forgeloop next` before each
496
- subsequent lifecycle action. `record-check` records results already observed by
497
- the agent; it never executes the supplied command text.
549
+ The host agent runs applicable checks after the receipt exists, uses `run-check`
550
+ for commands, and uses `record-check` for manual or non-command observations.
551
+ `run-check` records exact command provenance; `record-check` records supplied
552
+ metadata only and never executes its `--command` value. Query `forgeloop next`
553
+ before each subsequent lifecycle action.
498
554
 
499
555
  Continue until the terminal outcome is either validator-backed `COMPLETE` or
500
556
  an explicitly reported `BLOCKED` / `PARTIALLY VERIFIED` result with exact
@@ -128,6 +128,7 @@ The following protocol artifacts are strictly owned by ForgeLoop:
128
128
  - `.forgeloop/work-state.json`
129
129
  - `.forgeloop/events.ndjson`
130
130
  - `.forgeloop/execution-receipt.json`
131
+ - `.forgeloop/executions/<executionId>.json`
131
132
  - Canonical check, evidence, and terminal-result state
132
133
 
133
134
  If the required CLI or API capability cannot be resolved:
@@ -140,6 +141,38 @@ If the required CLI or API capability cannot be resolved:
140
141
 
141
142
  Report the corresponding ForgeLoop dimension as `NOT_VERIFIED` / `E_FORGELOOP_CLI_UNAVAILABLE`.
142
143
 
144
+ ## Trusted command provenance
145
+
146
+ Command verification has two explicit paths:
147
+
148
+ - `forgeloop run-check --id <id> --requirement <requirement> -- <argv>` owns
149
+ execution. It classifies the exact argv before launch, uses a non-shell
150
+ process boundary, records the target cwd, resolution mode, timestamps,
151
+ exit status, and task/check binding in
152
+ `.forgeloop/executions/<executionId>.json`, then records an `OBSERVED` check
153
+ with `provenance: FORGELOOP_EXECUTED`.
154
+ - `forgeloop record-check` owns serialization only. `--command` is metadata and
155
+ is never launched. A `kind: command` check with `evidenceKind: OBSERVED`
156
+ requires both `executionRef` and `FORGELOOP_EXECUTED`; manual or actor-reported
157
+ observations use their explicit non-command/provenance values and remain
158
+ distinguishable from process execution.
159
+
160
+ `run-check` rejects install-capable resolution before process launch unless the
161
+ host supplies a valid trusted authority context. `npm exec` and `npm x` are
162
+ installation-capable resolution paths. Recognized command dispatchers (such as
163
+ `npm test`, `npm restart`, `npm run`, `npm rum`, `npm urn`) are resolved
164
+ recursively across recognized lifecycle scripts before launch with cycle
165
+ detection, leading option normalization, and restart-specific lifecycle fallback.
166
+ npm workspace script executions (`--workspace`, `-w`, `--workspaces`, `--ws`) fail
167
+ closed before launch with `E_COMMAND_RESOLUTION_AMBIGUOUS` because the effective
168
+ `package.json` context cannot be proven from the root target. Unknown npm command semantics are rejected before execution rather than downgraded to local execution. ForgeLoop uses an explicit non-installing allowlist instead of assuming that unrecognized npm commands are safe. `npx --no-install` is
169
+ an allowed non-installing resolution and can return a normal failed result when
170
+ the requested tool is unavailable. Completion, audit, `validate-protocol`, and task
171
+ bundles revalidate execution references rather than trusting duplicated check
172
+ metadata. Invalid or missing references return `E_EXECUTION_REF_INVALID`; an
173
+ observed command without ForgeLoop provenance returns
174
+ `E_COMMAND_PROVENANCE_UNATTESTED`.
175
+
143
176
  ## Missing tool capability
144
177
 
145
178
  A missing tool is a capability gap, not installation authority.
@@ -152,6 +185,77 @@ not already available:
152
185
  - otherwise report the affected verification dimension as not verified with
153
186
  `E_VERIFICATION_TOOL_UNAVAILABLE`.
154
187
 
188
+ Every verification command is classified by resolution mode (`LOCAL_EXECUTABLE`,
189
+ `LOCAL_PACKAGE_BINARY`, `NON_INSTALLING_RESOLUTION`, `INSTALL_CAPABLE_RESOLUTION`,
190
+ `EXPLICIT_INSTALLATION`). Any command that uses an install-capable or installation
191
+ path without a valid canonical authority reference is rejected by `record-check`,
192
+ `audit`, and `complete` with `E_INSTALLATION_AUTHORITY_REQUIRED`, `E_AUTHORITY_INVALID`,
193
+ `E_AUTHORITY_SCOPE_MISMATCH`, or `E_AUTHORITY_UNTRUSTED_SOURCE`.
194
+
195
+ ```text
196
+ capability ≠ authority
197
+ evidence ≠ authority grant
198
+ actor claim ≠ operator grant
199
+ ```
200
+
201
+ Authority cannot be self-issued by the actor consuming it. Boolean fields inside
202
+ verification evidence are not sufficient proof of installation authority.
203
+
204
+ ### Authority provenance
205
+
206
+ Authority provenance is external to actor-authored project state. An external
207
+ path is not equivalent to external authority ownership:
208
+
209
+ ```text
210
+ outside target
211
+
212
+ outside actor control
213
+ ```
214
+
215
+ The standalone CLI uses `trustMode: NONE`. `FORGELOOP_AUTHORITY_FILE` and
216
+ `FORGELOOP_AUTHORITY_DIR` select candidate authority sources, but they do not
217
+ make a source trusted in actor-facing execution. Environment-selected sources
218
+ are rejected with `E_AUTHORITY_UNTRUSTED_SOURCE` for install-capable checks.
219
+
220
+ Trusted authority requires an explicit `HOST_ATTESTED` runtime context supplied
221
+ through an integration boundary the active actor cannot replace at command
222
+ invocation time. Configuration is not trust:
223
+
224
+ ```text
225
+ environment-selected source
226
+
227
+ host-attested source
228
+
229
+ configuration
230
+
231
+ trust
232
+ ```
233
+
234
+ The host-attested source must still resolve outside the actor-writable target. A
235
+ project-local authority reference may identify a grant, but it does not create
236
+ the root of trust.
237
+
238
+ ```text
239
+ actor-authored evidence
240
+
241
+ trusted authority
242
+
243
+ project-local file
244
+
245
+ host grant
246
+
247
+ declared provenance
248
+
249
+ verified provenance
250
+ ```
251
+
252
+ A local artifact claiming `source: operator` is not sufficient proof of operator
253
+ authority. The actor-facing CLI must not expose an equivalent of
254
+ `--authority-source-attested-by-host` or `--trusted-authority-file` that
255
+ self-promotes a source. If the host exposes the attested source as writable to
256
+ the actor, the host boundary has been compromised and ForgeLoop cannot provide
257
+ cryptographic attestation by itself.
258
+
155
259
  Never convert `PROTOCOL_LIMITED` into environmental mutation by implicitly
156
260
  installing a package.
157
261
 
package/README.md CHANGED
@@ -109,11 +109,15 @@ The regression suite injects failures at these boundaries and verifies that
109
109
  owned cleanup. The frozen published installation under
110
110
  [`tests/fixtures/legacy-0.1.6/`](./tests/fixtures/legacy-0.1.6/) is derived
111
111
  from the real npm tarball, includes provenance and digests, and is copied into
112
- The current published release is `@cassiomc1/forgeloop@0.1.13`.
113
- Earlier `0.1.8`, `0.1.9`, `0.1.10`, `0.1.11`, and `0.1.12` references are historical; never move
114
- their tags or `v0.1.10`. Version `0.1.13` enforces the missing verification tool
115
- policy, conditional single-actor delegation validation, and a universal
116
- vendor-neutral engineering protocol positioning.
112
+ The latest verified published npm release is `@cassiomc1/forgeloop@0.1.14`.
113
+ The repository package candidate is `@cassiomc1/forgeloop@0.1.15`; it is not
114
+ published yet.
115
+ Earlier `0.1.8`, `0.1.9`, `0.1.10`, `0.1.11`, `0.1.12`, and `0.1.13` references are historical; never move
116
+ their tags or `v0.1.10`. Release `0.1.14` enforces verification installation
117
+ authority, provides recoverable stale receipt lifecycle in `prepare-completion`,
118
+ and validates single-actor protocol runs. The `0.1.15` candidate adds trusted
119
+ command execution provenance without changing the v1 lifecycle or authority
120
+ boundary.
117
121
 
118
122
  ## How to prompt ForgeLoop
119
123
 
@@ -203,12 +207,14 @@ project without overwriting local instructions. When the package is available
203
207
  in the npm registry, use the commands below; otherwise use the repository
204
208
  checkout fallback.
205
209
 
206
- The current published release is `@cassiomc1/forgeloop@0.1.13`.
207
- Pin this version when a reproducible blind run or release-identity check is
208
- required:
210
+ The current repository package candidate is `@cassiomc1/forgeloop@0.1.15` and is
211
+ not yet published.
212
+ The latest verified published npm release is `@cassiomc1/forgeloop@0.1.14`.
213
+ For reproducible published-package runs or release-identity checks,
214
+ pin the published version:
209
215
 
210
216
  ```bash
211
- npx @cassiomc1/forgeloop@0.1.13 --version
217
+ npx @cassiomc1/forgeloop@0.1.14 --version
212
218
  npx @cassiomc1/forgeloop init
213
219
  npx @cassiomc1/forgeloop doctor
214
220
  npx @cassiomc1/forgeloop update
@@ -231,7 +237,8 @@ npx @cassiomc1/forgeloop advance --to PLANNED
231
237
  npx @cassiomc1/forgeloop advance --to EXECUTING
232
238
  npx @cassiomc1/forgeloop advance --to VERIFYING
233
239
  npx @cassiomc1/forgeloop prepare-completion --json
234
- npx @cassiomc1/forgeloop record-check --id tests --requirement tests --status passed --evidence-kind OBSERVED --command "npm test" --result "exit 0" --exit-code 0 --json
240
+ npx @cassiomc1/forgeloop run-check --json --id tests --requirement tests -- npm test
241
+ npx @cassiomc1/forgeloop record-check --id docs-review --kind manual-review --requirement "documentation synchronized" --status passed --evidence-kind OBSERVED --provenance MANUAL_OBSERVATION --result "reviewed" --json
235
242
  npx @cassiomc1/forgeloop record-terminal-result --requirement "Package published" --type PUBLICATION --status published --source "npm publish" --result "Published package to npm" --json
236
243
  npx @cassiomc1/forgeloop advance --to REVIEWING
237
244
  npx @cassiomc1/forgeloop audit --json
@@ -261,7 +268,7 @@ implementation
261
268
  → forgeloop next
262
269
  → prepare-completion
263
270
  → forgeloop next
264
- → checks + record-check
271
+ → checks + run-check/record-check
265
272
  → forgeloop next
266
273
  → advance --to REVIEWING
267
274
  → forgeloop next
@@ -285,10 +292,15 @@ Before implementation, write the canonical contract, persist the route, create
285
292
  required gate artifacts under `.forgeloop/gates/`, and require `preflight` to
286
293
  return `READY`. `advance` enforces legal phase transitions; it never runs the
287
294
  project's commands. After implementation, advance to `VERIFYING`, use
288
- `prepare-completion` to create a safe receipt skeleton, and use `record-check`
289
- to serialize results that the agent has already observed. `record-check` never
290
- executes the supplied command text. Advance to `REVIEWING` before running
291
- `audit` and `complete`.
295
+ `prepare-completion` to create a safe receipt skeleton, use `run-check` for
296
+ commands, and use `record-check` for manual or non-command observations.
297
+ `run-check` accepts the exact argv after `--`, classifies resolution before
298
+ launch, blocks install-capable resolution without trusted host authority, and
299
+ writes `.forgeloop/executions/<executionId>.json` before recording the check.
300
+ `record-check` never executes `--command`; that option is metadata only. A
301
+ command check with `OBSERVED` evidence must reference a ForgeLoop execution
302
+ artifact with `provenance: FORGELOOP_EXECUTED`. Advance to `REVIEWING` before
303
+ running `audit` and `complete`.
292
304
  `audit` is a read-only consistency check. `complete` validates the final
293
305
  contract, route, gates, phase ledger, structured evidence, coverage, receipt,
294
306
  and freshness before it can return `VALID`. `report` renders the same result as
@@ -372,12 +384,18 @@ target project. Its main threat boundaries are:
372
384
  | Data exposure | Receipts and checkpoints reject secret-like keys and values; examples use placeholders, and the repository secret scanner runs in CI. |
373
385
  | Unsafe update overwrite | `update` preserves locally modified files and the target's `.forgeloop/kit/PROJECT_PROFILE.md`; adoption and writes remain bounded to the selected target. |
374
386
  | Dependency supply chain | Runtime code uses Node built-ins only; the package does not install agents, providers, plugins, or remote services. |
387
+ | Installation authority provenance | Standalone CLI uses `trustMode: NONE`: environment-selected `FORGELOOP_AUTHORITY_FILE`/`FORGELOOP_AUTHORITY_DIR` sources are untrusted candidates; only an internal `HOST_ATTESTED` context may select a trusted source outside the actor-writable target. Project-local authority claims remain untrusted. |
375
388
  | Stale replay | Work state records contract and repository fingerprints; drift requires revalidation and never reruns destructive or publication actions automatically. |
376
389
  | Unverified publication | Receipts carry explicit publication booleans; local success never implies a push, pull request, merge, release, or deployment. |
390
+ | Unattested observed command | `record-check --command` is metadata only; command `OBSERVED` evidence requires a bound ForgeLoop execution artifact. `run-check` preserves exact argv, target cwd, resolution mode, timestamps, and exit status, and rejects install-capable resolution before launch without trusted host authority. |
377
391
 
378
392
  The full boundary inventory, residual limitations, and executable evidence are
379
393
  in [`THREAT_MODEL.md`](./THREAT_MODEL.md).
380
394
 
395
+ An external path is not equivalent to external authority ownership. Actor-controlled
396
+ environment configuration is not sufficient proof of host/operator authority;
397
+ trusted authority requires a host-attested integration boundary.
398
+
381
399
  The CLI cannot protect a target from a separately privileged or hostile process
382
400
  that changes the filesystem after validation. Consumers must still review
383
401
  permissions, package provenance, and external actions before granting authority.
@@ -642,7 +660,7 @@ adoption. Local rendering requires Node.js 22+ and FFmpeg.
642
660
  The source repository keeps canonical documents at the root for package
643
661
  development and validation. A bootstrapped target uses the hidden-kit layout
644
662
  shown above; mutable contract, route, state, gate, event, preflight, and
645
- receipt artifacts remain directly under `.forgeloop/`.
663
+ receipt and execution artifacts remain directly under `.forgeloop/`.
646
664
 
647
665
  ## Maintenance
648
666
 
package/THREAT_MODEL.md CHANGED
@@ -20,6 +20,7 @@ remaining trust boundaries and their executable evidence.
20
20
  | 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
21
  | 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
22
  | 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` |
23
+ | Unattested observed command | An actor supplies `--command "..."` or forged command metadata and makes an unrun process appear to be observed evidence | Check provenance, execution artifact, and process boundary | `run-check` captures exact argv, cwd, resolution, timestamps, exit status, and task/check binding; it classifies before launch, uses `shell: false`, and rejects install-capable resolution without trusted authority. `record-check --command` is metadata only; command `OBSERVED` checks require `FORGELOOP_EXECUTED` plus a valid `executionRef`; completion, audit, protocol validation, and bundles revalidate it | The local execution artifact is not cryptographic remote attestation, and a separately privileged process can alter the target after execution | `tests/run-check.test.js`, `tests/completion-cli.test.js`, `tests/verification-capability.test.js`, `tests/validate-protocol-cli.test.js` |
23
24
  | Malicious receipt | Turns local claims into false publication or completion claims | Execution receipt JSON | Semantic evidence checks for completion, checks, review, push, commit, and deployment; explicit publication booleans | Evidence text is declarative and must still be reviewed for provenance | `tests/receipt-semantics.test.js`, `tests/observability.test.js` |
24
25
  | Malicious task brief | Grants a child task more authority than intended | Delegation brief JSON and host harness | Relative path boundaries, guide/verification/authority checks, secret-free validation, set validation, parent integration ownership | The host harness remains responsible for OS permissions and execution policy | `tests/delegation.test.js`, `tests/delegation-set.test.js` |
25
26
  | Artifact content exposure | Sensitive material enters portable artifacts or diagnostics | State, receipt, delegation, evidence, and repository text | Nested key/value detection, shaped marker patterns, scanner coverage, no content echo in errors | Content scanners cannot prove that an unknown encoding is harmless | `tests/security-limits.test.js`, `tests/test_scan_secrets.py`, `scripts/scan_secrets.py` |
@@ -35,6 +36,14 @@ remaining trust boundaries and their executable evidence.
35
36
  | Lifecycle simulation after CLI resolution failure | A runtime manually writes protocol-owned JSON and falsely claims conformance when the CLI is unresolved | Lifecycle-owned protocol state and CLI availability | CLI-owned artifact policy, universal adapter prohibition, validator-backed completion, append-only ledger hash chain | A privileged local process can tamper with local files; ForgeLoop detects consistency, not remote attestation | `tests/discovery-surfaces.test.js`, `tests/lifecycle.test.js`, `LOOP_ENGINEERING.md` |
36
37
  | Unauthorized verification dependency installation | The active actor mutates the environment by downloading or installing a missing checker merely to satisfy verification | Verification capability discovery and installation authority | Missing verification tool policy, non-installing resolution first, explicit installation authority, equivalent-check fallback, NOT_VERIFIED degradation | A privileged external process may still install tools outside ForgeLoop's control | `tests/verification-capability.test.js`, `tests/discovery-surfaces.test.js`, `LOOP_ENGINEERING.md` |
37
38
  | False delegation requirement | A valid single-actor run is incorrectly reported as incomplete because a validator demands artifacts for delegation that never occurred | Validator delegation scope resolution | Canonical delegationIsInScope predicate, conditional delegation validation in validateTaskArtifactSet and validate-protocol | Malformed or externally injected artifacts may require INCONSISTENT classification | `tests/conformance.test.js`, `tests/validate-protocol-cli.test.js` |
39
+ | Self-asserted authority bypass | The active actor supplies `installationAuthorized=true` inside its own verification evidence and thereby grants itself authority | Authority provenance and verification evidence | Boolean claims are ignored; scoped authority references, task/type/tool validation, and validator revalidation in `record-check`/`audit`/`complete` require a trusted source | A host-controlled source is still a semantic trust boundary and is not cryptographic attestation | `tests/verification-capability.test.js`, `tests/authority.test.js`, `tests/stale-receipt-recovery.test.js` |
40
+ | Forged local authority artifact | The active actor creates `.forgeloop/authorities/auth-modlens.json`, claims `source=operator`, and uses the reference to authorize its own installation-capable check | Host/operator authority source versus actor-writable project state | Resolve grants only from an explicit `HOST_ATTESTED` runtime context with an external source outside the target; reject project-local grants with `E_AUTHORITY_UNTRUSTED_SOURCE`; revalidate in `record-check`/`audit`/`complete` | If the host exposes the attested source as writable to the actor, ForgeLoop cannot distinguish genuine grants from actor fabrication without a stronger trust anchor | Local fake rejection, host-attested external acceptance, inside-target rejection, post-record removal and revocation tests |
41
+ | Environment-injected trust root | The active actor creates an authority file outside the project target and sets `FORGELOOP_AUTHORITY_FILE` or `FORGELOOP_AUTHORITY_DIR` when invoking ForgeLoop | Actor-controlled process environment versus host-attested runtime authority | Standalone CLI uses `trustMode: NONE`; environment-selected sources are metadata/candidates only and fail with `E_AUTHORITY_UNTRUSTED_SOURCE`; trusted authority requires an internal `HOST_ATTESTED` context not exposed as a self-assertable CLI option | If the host integration allows the actor to mutate or replace the attested source/context, the host trust boundary is compromised | Environment-injection rejection, standalone audit/complete rejection, host-attested positive path |
42
+ | Stale receipt recovery dead-end | Work state changes after preparing a receipt, leaving a mismatch that cannot be refreshed because the old receipt is rejected during re-preparation | Preparation lifecycle and recovery action resolution | Recoverable stale receipt binding in `prepareCompletion`, executable `PREPARE_COMPLETION` return from `next`, atomic refresh of stateFingerprint and changedPaths | Manual file corruption outside CLI commands requires manual diagnostic recovery | `tests/stale-receipt-recovery.test.js`, `tests/next-executability.test.js` |
43
+ | Recursive npm script dispatch | A recognized npm lifecycle script invokes another npm script, which later invokes an installation-capable resolver (e.g. `test` -> `npm run visual` -> `npx package`) | Recognized npm dispatcher semantics before ForgeLoop process launch | Recursive npm-script resolution with cycle detection, maximum depth (16), lifecycle hook inspection, restart special semantics, and fail-closed behavior when the resolver cannot prove the chain is non-installing | Opaque executables may spawn arbitrary descendants. Full descendant-process attestation requires host-level process controls and is outside this release | `tests/run-check.test.js`, `tests/verification-capability.test.js` |
44
+ | npm invocation rewriting and workspace dispatch | npm configuration flags appear before the subcommand, or npm workspace selectors cause script execution to occur against a package.json different from the ForgeLoop target root | Raw npm argv versus effective npm command and execution context | Canonical npm invocation parsing, effective subcommand extraction, workspace flag detection across the full npm argv, and fail-closed workspace script handling when the selected package.json cannot be proven from the current target | ForgeLoop 0.1.15 intentionally does not implement full npm workspace resolution. Users should execute run-check from the selected workspace target directory | `tests/run-check.test.js`, `tests/verification-capability.test.js` |
45
+ | Unclassified npm Install-Capable Command | The npm security classifier recognizes only a small denylist of package-mutating commands. Another official npm command or alias with install/update/bootstrap semantics falls through as a local package command | Effective npm command semantics versus ForgeLoop's command classifier | Semantic npm command classification with explicit install-capable families, explicit script-dispatch families, a deliberately small non-installing allowlist, and fail-closed behavior for unknown or ambiguous npm commands | Future npm commands are blocked until ForgeLoop explicitly classifies them | `tests/verification-capability.test.js`, `tests/run-check.test.js` |
46
+ | npm Option Value Ambiguity | An unknown npm config option with a separate value appears before the effective subcommand, and a parser misinterprets the option value as the npm subcommand | Raw npm argv and unsupported config syntax | Recognize self-contained `--key=value`, explicitly supported options-with-value, and known boolean options. Unknown long option followed by a non-option token fails closed with `NPM_OPTION_VALUE_AMBIGUOUS` | Unsupported npm config grammar is intentionally rejected rather than guessed | `tests/verification-capability.test.js`, `tests/run-check.test.js` |
38
47
 
39
48
  ## Boundary rules
40
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cassiomc1/forgeloop",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Portable, verifiable engineering protocol for AI coding environments and developer workflows",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "forgeloop://schemas/authority.schema.json",
4
+ "title": "ForgeLoop installation authority grant",
5
+ "type": "object",
6
+ "required": [
7
+ "schemaVersion",
8
+ "protocolVersion",
9
+ "authorityId",
10
+ "taskId",
11
+ "type",
12
+ "status",
13
+ "scope",
14
+ "source"
15
+ ],
16
+ "properties": {
17
+ "schemaVersion": { "const": 1 },
18
+ "protocolVersion": { "const": 1 },
19
+ "authorityId": { "type": "string", "minLength": 1 },
20
+ "taskId": { "type": "string", "minLength": 1 },
21
+ "type": { "enum": ["SOFTWARE_INSTALLATION"] },
22
+ "status": { "enum": ["AUTHORIZED", "REVOKED", "EXPIRED"] },
23
+ "scope": {
24
+ "type": "object",
25
+ "required": ["tool"],
26
+ "properties": {
27
+ "tool": { "type": "string", "minLength": 1 }
28
+ },
29
+ "additionalProperties": false
30
+ },
31
+ "source": { "enum": ["operator", "host", "project-policy"] }
32
+ },
33
+ "additionalProperties": false
34
+ }
@@ -13,6 +13,8 @@
13
13
  "status": { "enum": ["passed", "failed", "blocked", "not-run"] },
14
14
  "evidenceKind": { "enum": ["OBSERVED", "INFERRED", "NOT_VERIFIED", "BLOCKED"] },
15
15
  "source": { "type": "string", "minLength": 1 },
16
+ "executionRef": { "type": "string", "minLength": 1 },
17
+ "provenance": { "enum": ["FORGELOOP_EXECUTED", "ACTOR_REPORTED", "MANUAL_OBSERVATION"] },
16
18
  "exitCode": { "type": "integer" },
17
19
  "timestamp": { "type": "string", "minLength": 1 },
18
20
  "repositoryFingerprint": { "type": "string", "pattern": "^[a-f0-9]{40}$" },
@@ -0,0 +1,63 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "forgeloop://schemas/execution.schema.json",
4
+ "title": "ForgeLoop command execution artifact",
5
+ "type": "object",
6
+ "required": [
7
+ "schemaVersion",
8
+ "protocolVersion",
9
+ "executionId",
10
+ "taskId",
11
+ "checkId",
12
+ "requirement",
13
+ "verificationCycle",
14
+ "kind",
15
+ "argv",
16
+ "cwd",
17
+ "resolution",
18
+ "startedAt",
19
+ "finishedAt",
20
+ "status",
21
+ "exitCode"
22
+ ],
23
+ "properties": {
24
+ "schemaVersion": { "const": 1 },
25
+ "protocolVersion": { "const": 1 },
26
+ "executionId": { "type": "string", "minLength": 1 },
27
+ "taskId": { "type": "string", "minLength": 1 },
28
+ "checkId": { "type": "string", "minLength": 1 },
29
+ "requirement": { "type": "string", "minLength": 1 },
30
+ "verificationCycle": { "type": "integer", "minimum": 1 },
31
+ "kind": { "const": "COMMAND_EXECUTION" },
32
+ "argv": {
33
+ "type": "array",
34
+ "minItems": 1,
35
+ "items": { "type": "string", "minLength": 1 }
36
+ },
37
+ "cwd": { "type": "string", "minLength": 1 },
38
+ "resolution": {
39
+ "type": "object",
40
+ "required": ["resolutionMode", "mayInstall", "installer", "tool"],
41
+ "properties": {
42
+ "resolutionMode": { "type": "string", "minLength": 1 },
43
+ "mayInstall": { "type": "boolean" },
44
+ "installer": { "oneOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] },
45
+ "tool": { "oneOf": [{ "type": "string", "minLength": 1 }, { "type": "null" }] }
46
+ },
47
+ "additionalProperties": false
48
+ },
49
+ "dispatch": {
50
+ "type": "object",
51
+ "properties": {
52
+ "kind": { "type": "string", "minLength": 1 },
53
+ "scriptName": { "type": "string", "minLength": 1 }
54
+ },
55
+ "additionalProperties": false
56
+ },
57
+ "startedAt": { "type": "string", "minLength": 1 },
58
+ "finishedAt": { "type": "string", "minLength": 1 },
59
+ "status": { "enum": ["passed", "failed"] },
60
+ "exitCode": { "oneOf": [{ "type": "integer", "minimum": 0 }, { "type": "null" }] }
61
+ },
62
+ "additionalProperties": false
63
+ }