@cassiomc1/forgeloop 1.8.1 → 1.10.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/.cursor/rules/project-loop.mdc +6 -3
- package/.github/copilot-instructions.md +5 -0
- package/AGENTS.md +6 -0
- package/AGENT_COMPATIBILITY.md +15 -0
- package/CLAUDE.md +6 -0
- package/DELEGATION_PROTOCOL.md +6 -0
- package/DOCS_INDEX.md +9 -2
- package/ENG/accessibility-eng.md +12 -2
- package/ENG/design-code-eng.md +22 -1
- package/LOOP_ENGINEERING.md +41 -0
- package/LOOP_SYSTEM_DESIGN.md +33 -0
- package/ORCHESTRATOR_INTEGRATION.md +9 -0
- package/PROTOCOL_INTEGRATION.md +57 -0
- package/QUALITY_SCORECARD.md +2 -0
- package/README.md +51 -0
- package/TERMINOLOGY.md +12 -0
- package/THREAT_MODEL.md +48 -0
- package/completions/_forgeloop +5 -1
- package/completions/forgeloop.bash +9 -1
- package/completions/forgeloop.fish +27 -1
- package/docs/ADVISORY_CONTEXT.md +174 -0
- package/docs/AGENT_PROTOCOL_SUMMARY.md +33 -2
- package/docs/ARTIFACT_REFERENCE.md +142 -0
- package/docs/CLI_REFERENCE.md +124 -1
- package/docs/CROSS_HARNESS_CONTINUITY.md +85 -0
- package/docs/DOCUMENTATION_GUIDE.md +7 -0
- package/docs/GETTING_STARTED.md +22 -0
- package/docs/KNOWLEDGE_SOURCES.md +171 -0
- package/docs/MCP.md +17 -1
- package/docs/RECIPES.md +111 -0
- package/docs/RELEASE_CHECKLIST.md +14 -0
- package/docs/STRUCTURAL_QUALITY.md +350 -0
- package/docs/TROUBLESHOOTING.md +161 -2
- package/docs/UNIVERSAL_INTEGRATION.md +60 -0
- package/package.json +4 -1
- package/schemas/config.schema.json +46 -0
- package/schemas/handoff-envelope.schema.json +1 -0
- package/schemas/preflight.schema.json +2 -1
- package/schemas/structural-quality.schema.json +175 -0
- package/scripts/check-changelog-freshness.mjs +27 -3
- package/scripts/generate-agent-protocol-summary.mjs +18 -0
- package/src/cli.js +24 -0
- package/src/commands/handoff-accept.js +36 -0
- package/src/commands/handoff-list.js +28 -2
- package/src/commands/handoff-show.js +27 -2
- package/src/commands/quality-baseline.js +28 -0
- package/src/commands/quality-status.js +34 -0
- package/src/commands/quality-verify.js +30 -0
- package/src/commands/reconcile-continuity.js +4 -0
- package/src/core/advisory-context/constants.js +74 -0
- package/src/core/advisory-context/provider.js +287 -0
- package/src/core/advisory-context/service.js +140 -0
- package/src/core/artifact-registry.js +12 -0
- package/src/core/audit.js +38 -0
- package/src/core/bundles.js +134 -1
- package/src/core/cli-command-definitions.js +62 -0
- package/src/core/command-executors.js +28 -0
- package/src/core/command-input.js +23 -1
- package/src/core/completion-artifacts.js +2 -0
- package/src/core/completion.js +42 -0
- package/src/core/config.js +3 -0
- package/src/core/continuity-lint.js +89 -0
- package/src/core/continuity-reconciliation.js +16 -0
- package/src/core/continuity.js +10 -11
- package/src/core/error-codes.js +186 -0
- package/src/core/events.js +32 -0
- package/src/core/execution-profile-context.js +15 -1
- package/src/core/filesystem.js +34 -3
- package/src/core/handoff-acceptance.js +277 -0
- package/src/core/handoff.js +41 -8
- package/src/core/inspect.js +64 -0
- package/src/core/integration-invocation-policy.js +34 -2
- package/src/core/integration-resources.js +38 -1
- package/src/core/next-action-model.js +11 -1
- package/src/core/next-action-phases.js +84 -5
- package/src/core/phase.js +9 -1
- package/src/core/portable-context.js +103 -0
- package/src/core/preflight.js +33 -0
- package/src/core/protocol-info.js +33 -2
- package/src/core/runtime-context.js +58 -0
- package/src/core/schema-validation.js +1 -0
- package/src/core/structural-quality/artifacts.js +329 -0
- package/src/core/structural-quality/constants.js +67 -0
- package/src/core/structural-quality/policy.js +227 -0
- package/src/core/structural-quality/provider.js +287 -0
- package/src/core/structural-quality/sentrux-mcp.js +477 -0
- package/src/core/structural-quality/service.js +1138 -0
- package/src/core/structural-quality/source-fingerprint.js +112 -0
- package/src/core/structural-quality/status.js +3 -0
- package/src/core/task-paths.js +24 -0
- package/src/core/templates.js +1 -0
- package/src/integration.d.ts +141 -0
- package/src/integration.js +36 -0
package/docs/MCP.md
CHANGED
|
@@ -25,6 +25,9 @@ Two transports ship in one package:
|
|
|
25
25
|
- **Recovery acknowledgement is not authorization.** `acknowledgeRecovery`
|
|
26
26
|
in tool input only satisfies ForgeLoop's caller acknowledgement after the
|
|
27
27
|
server was started with recovery capability.
|
|
28
|
+
- **Advisory context is host-injected only.** The core Integration API supports
|
|
29
|
+
explicit provider injection, but the stock MCP adapter must not fabricate,
|
|
30
|
+
auto-discover, or persist an advisory provider or its results.
|
|
28
31
|
|
|
29
32
|
## Modes
|
|
30
33
|
|
|
@@ -84,6 +87,19 @@ content.
|
|
|
84
87
|
Raw recovery artifacts, transaction journals, lock files, and unbounded event
|
|
85
88
|
ledgers are intentionally not exposed.
|
|
86
89
|
|
|
90
|
+
The `handoff-accept` mutating command is available only through a mode that
|
|
91
|
+
allows loop mutations; `readonly` intentionally hides it. When exposed, it
|
|
92
|
+
records one canonical `HANDOFF_ACCEPTED` operational receipt and preserves the
|
|
93
|
+
same freshness, consumer-idempotency, ledger, and no-claim-transfer rules as
|
|
94
|
+
the CLI and Integration API. MCP transport metadata cannot authenticate a
|
|
95
|
+
`consumerId`, establish authority, or turn receipt of a message into
|
|
96
|
+
acceptance.
|
|
97
|
+
|
|
98
|
+
Advisory provider recall is not a stock MCP resource or command. A host that
|
|
99
|
+
needs advisory context injects a provider into the core Integration API and
|
|
100
|
+
performs an explicit bounded recall itself. MCP must never auto-recall context
|
|
101
|
+
for startup, status, next, task/context, or any other canonical projection.
|
|
102
|
+
|
|
87
103
|
The context resource is read-only. It lets an MCP host adapt presentation depth
|
|
88
104
|
from the canonical resolved execution profile while preserving lifecycle
|
|
89
105
|
phases, required gates, verification truth, authority, provenance, and
|
|
@@ -119,7 +135,7 @@ forgeloop-mcp-http --project /repo --mode safe # 127.0.0.1:3333
|
|
|
119
135
|
|
|
120
136
|
| Component | Current contract |
|
|
121
137
|
| --- | --- |
|
|
122
|
-
| ForgeLoop core package | `>=1.5.0 <2` dependency range; current
|
|
138
|
+
| ForgeLoop core package | `>=1.5.0 <2` dependency range; current release `1.10.0` |
|
|
123
139
|
| ForgeLoop protocol | `1` |
|
|
124
140
|
| Integration API | `1` |
|
|
125
141
|
| MCP package | `0.1.x` initial package |
|
package/docs/RECIPES.md
CHANGED
|
@@ -28,6 +28,7 @@ Concise, copy-paste friendly recipes for common ForgeLoop tasks.
|
|
|
28
28
|
20. [Configure Trusted Narrow Verification](#recipe-20--configure-trusted-narrow-verification)
|
|
29
29
|
21. [Generate and Verify Code Attestation](#recipe-21--generate-and-verify-code-attestation)
|
|
30
30
|
22. [Verify a Revision Range](#recipe-22--verify-a-revision-range)
|
|
31
|
+
23. [Run Structural Quality Feedback](#recipe-23--run-structural-quality-feedback)
|
|
31
32
|
|
|
32
33
|
---
|
|
33
34
|
|
|
@@ -456,6 +457,86 @@ operational context only: a handoff is not delegation, authority, independent
|
|
|
456
457
|
review evidence, or completion evidence. Use `continuity.json` for mutable
|
|
457
458
|
resume notes and canonical execution artifacts for proof.
|
|
458
459
|
|
|
460
|
+
### Recipe 18A — Accept an Immutable Handoff Exactly Once
|
|
461
|
+
|
|
462
|
+
After inspecting the snapshot and confirming that the receiving harness is
|
|
463
|
+
actually consuming it, record the operational receipt:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
forgeloop handoff-accept --task task-001 \
|
|
467
|
+
--handoff <handoffId> \
|
|
468
|
+
--consumer-id agent-session-42 \
|
|
469
|
+
--harness codex \
|
|
470
|
+
--json
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
Retrying with the same consumer is idempotent. A different consumer receives
|
|
474
|
+
`E_HANDOFF_ALREADY_ACCEPTED`. Acceptance is operational only: it does not
|
|
475
|
+
transfer claims, create evidence, approve delegation, or grant authority.
|
|
476
|
+
|
|
477
|
+
### Recipe 18B — Diagnose an Inconsistent Handoff
|
|
478
|
+
|
|
479
|
+
Inspect the derived projection and ledger before attempting any repair:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
forgeloop handoff-list --task task-001 --json
|
|
483
|
+
forgeloop handoff-show --task task-001 --id <handoffId> --json
|
|
484
|
+
forgeloop validate-protocol --task task-001 --json
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
`INCONSISTENT` is fail-closed. Check the returned reason codes for a stale
|
|
488
|
+
contract/route/repository snapshot, an unbound legacy handoff, a digest mismatch,
|
|
489
|
+
or invalid acceptance history. Do not edit the immutable handoff or
|
|
490
|
+
`events.ndjson`; create a fresh handoff after the canonical issue is resolved.
|
|
491
|
+
|
|
492
|
+
### Recipe 18C — Use an Advisory Provider from a Host Integration
|
|
493
|
+
|
|
494
|
+
Register a provider in runtime context and invoke recall explicitly:
|
|
495
|
+
|
|
496
|
+
```javascript
|
|
497
|
+
import {
|
|
498
|
+
createForgeLoopContext,
|
|
499
|
+
recallAdvisoryContext,
|
|
500
|
+
} from "@cassiomc1/forgeloop/integration";
|
|
501
|
+
|
|
502
|
+
const runtimeContext = createForgeLoopContext({
|
|
503
|
+
advisoryContextProviders: {
|
|
504
|
+
"host-context": {
|
|
505
|
+
id: "host-context",
|
|
506
|
+
recall: async ({ query }) => ({ items: await hostLookup(query) }),
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
const result = await recallAdvisoryContext({
|
|
512
|
+
target: ".",
|
|
513
|
+
taskId: "task-001",
|
|
514
|
+
providerName: "host-context",
|
|
515
|
+
query: "current authentication constraints",
|
|
516
|
+
runtimeContext,
|
|
517
|
+
});
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Recall is lazy, bounded, opt-in, non-persisted, non-evidence, and
|
|
521
|
+
non-executable. Validate every proposed change against canonical state and
|
|
522
|
+
verification instead of executing provider text.
|
|
523
|
+
|
|
524
|
+
### Recipe 18D — Resume with Continuity Lint Warnings
|
|
525
|
+
|
|
526
|
+
Treat lint findings as inspection hints only:
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
forgeloop continuity --task task-001 --json
|
|
530
|
+
forgeloop reconcile-continuity --task task-001 --json
|
|
531
|
+
forgeloop next --task task-001 --json
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Findings such as `CONTINUITY_REMAINING_ALREADY_COMPLETED`,
|
|
535
|
+
`CONTINUITY_FOCUS_ALREADY_COMPLETED`, `CONTINUITY_ITEM_ROLE_CONFLICT`,
|
|
536
|
+
`CONTINUITY_INSPECT_PATH_MISSING`, and `CONTINUITY_EMPTY_HINT_SET` are
|
|
537
|
+
non-authoritative and non-evidence. Refresh the note with
|
|
538
|
+
`record-continuity` when useful, then follow the canonical next action.
|
|
539
|
+
|
|
459
540
|
---
|
|
460
541
|
|
|
461
542
|
### Recipe 19 — Apply a Responsibility Contract
|
|
@@ -551,6 +632,36 @@ coverage gap or conflicting task digest is invalid; provider or invocation
|
|
|
551
632
|
failure is an error. This post-completion range result is distinct from the
|
|
552
633
|
pre-completion verification scope used by one checker.
|
|
553
634
|
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
### Recipe 23 — Run Structural Quality Feedback
|
|
638
|
+
|
|
639
|
+
Enable `structuralQuality` in `.forgeloop/config.json` with `observe` for
|
|
640
|
+
non-blocking evidence or `gate` for a completion requirement. The configured
|
|
641
|
+
provider is selected by name; executable paths and shell fragments are not
|
|
642
|
+
accepted.
|
|
643
|
+
|
|
644
|
+
```bash
|
|
645
|
+
# Capture after planning and before execution.
|
|
646
|
+
forgeloop quality-baseline --task task-001 --json
|
|
647
|
+
|
|
648
|
+
# Enter the normal lifecycle and evaluate the current verification cycle.
|
|
649
|
+
forgeloop advance --task task-001 --to EXECUTING --json
|
|
650
|
+
forgeloop advance --task task-001 --to VERIFYING --json
|
|
651
|
+
forgeloop quality-verify --task task-001 --json
|
|
652
|
+
|
|
653
|
+
# Inspect evidence without starting the provider.
|
|
654
|
+
forgeloop quality-status --task task-001 --json
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
In `gate` mode, a failed comparison follows the existing
|
|
658
|
+
`VERIFYING -> DIAGNOSING -> CORRECTING -> VERIFYING` loop. Record a diagnosis
|
|
659
|
+
from the evaluation artifact before correcting code. In `observe` mode,
|
|
660
|
+
unavailable or incomparable evidence remains visible as `NOT_OBSERVED` and
|
|
661
|
+
does not block completion by itself. See
|
|
662
|
+
[`STRUCTURAL_QUALITY.md`](./STRUCTURAL_QUALITY.md) for policy, provider,
|
|
663
|
+
Sentrux, bundle, and error-code details.
|
|
664
|
+
|
|
554
665
|
## Run ForgeLoop through MCP (safe mode)
|
|
555
666
|
|
|
556
667
|
Start the local MCP adapter and inspect what it exposes:
|
|
@@ -16,6 +16,20 @@ preparation and verification checklist; it does not authorize publication.
|
|
|
16
16
|
|
|
17
17
|
## Protocol and attestation
|
|
18
18
|
|
|
19
|
+
- [ ] `protocol-info` and the Integration API capability contracts agree.
|
|
20
|
+
- [ ] `canonicalHandoffs` v2 is advertised consistently.
|
|
21
|
+
- [ ] `advisoryContextProviders` v1 is advertised consistently.
|
|
22
|
+
- [ ] Advisory context remains Integration-API-only.
|
|
23
|
+
- [ ] `next`, `status`, and `task/context` invoke zero advisory providers.
|
|
24
|
+
- [ ] Advisory request budgets are normalized before provider invocation.
|
|
25
|
+
- [ ] Advisory results are never persisted by ForgeLoop.
|
|
26
|
+
- [ ] Same-consumer handoff acceptance is idempotent.
|
|
27
|
+
- [ ] Different-consumer handoff acceptance fails closed.
|
|
28
|
+
- [ ] Concurrent acceptance creates one `HANDOFF_ACCEPTED` event.
|
|
29
|
+
- [ ] Clean HEAD/branch drift rejects handoff acceptance.
|
|
30
|
+
- [ ] Stale contract/route identity rejects handoff creation or acceptance.
|
|
31
|
+
- [ ] An invalid event ledger projects `INCONSISTENT`.
|
|
32
|
+
- [ ] Continuity lint remains non-authoritative and non-evidence.
|
|
19
33
|
- [ ] `npm run dependency:policy` passes without adding runtime dependencies.
|
|
20
34
|
- [ ] `npm run lint` passes.
|
|
21
35
|
- [ ] `npm test` passes.
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# Structural Quality Feedback Loop
|
|
2
|
+
|
|
3
|
+
ForgeLoop can optionally compare the structure of a project before and after a
|
|
4
|
+
task. The provider is an external sensor; ForgeLoop owns the policy, evidence,
|
|
5
|
+
lifecycle, and completion decision.
|
|
6
|
+
|
|
7
|
+
## 1. Purpose and boundaries
|
|
8
|
+
|
|
9
|
+
Structural quality answers whether the measured dependency structure changed
|
|
10
|
+
within the configured budget. It does not prove behavioral correctness,
|
|
11
|
+
security, performance, accessibility, maintainability in general, or product
|
|
12
|
+
quality. Tests, lint, security checks, performance checks, accessibility checks,
|
|
13
|
+
review, and publication remain separate evidence dimensions.
|
|
14
|
+
|
|
15
|
+
ForgeLoop persists only normalized, bounded, secret-free observations. The
|
|
16
|
+
resolved project path is execution context and is not written into portable
|
|
17
|
+
quality artifacts.
|
|
18
|
+
|
|
19
|
+
## 2. Why structural quality is not a guide
|
|
20
|
+
|
|
21
|
+
Engineering guides tell an agent how to work. A structural-quality provider
|
|
22
|
+
measures the result of that work. The result is therefore a typed verification
|
|
23
|
+
artifact and a canonical check, not an `ENG/` guide or a replacement for one.
|
|
24
|
+
|
|
25
|
+
## 3. The five metrics
|
|
26
|
+
|
|
27
|
+
Every provider observation contains integer scores from `0` through `10000`, a
|
|
28
|
+
finite raw value, and a canonical bottleneck. The current Sentrux adapter maps
|
|
29
|
+
these five root causes:
|
|
30
|
+
|
|
31
|
+
| Root cause | Meaning in the feedback loop |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `modularity` | How cleanly responsibilities and communities are separated. |
|
|
34
|
+
| `acyclicity` | Whether dependency relationships remain free of prohibited cycles. |
|
|
35
|
+
| `depth` | The measured dependency-level depth of the project. |
|
|
36
|
+
| `equality` | How evenly structure is distributed across the measured modules. |
|
|
37
|
+
| `redundancy` | The amount of repeated or structurally redundant information. |
|
|
38
|
+
|
|
39
|
+
The aggregate `qualitySignal` is provider-supplied and normalized by ForgeLoop.
|
|
40
|
+
ForgeLoop does not reimplement graph analysis or claim that a high signal is a
|
|
41
|
+
universal software-quality score.
|
|
42
|
+
|
|
43
|
+
## 4. Delta-first policy
|
|
44
|
+
|
|
45
|
+
Gate decisions compare the current observation with the immutable baseline.
|
|
46
|
+
By default, the aggregate budget is zero (`maxRegressionPoints: 0`), new cycles
|
|
47
|
+
are forbidden (`forbidNewCycles: true`), and individual dimension budgets are
|
|
48
|
+
unenforced (`null`), allowing flexible dimension trade-offs as long as aggregate
|
|
49
|
+
signal does not regress. A configured dimension budget is intentional policy and
|
|
50
|
+
is bound to the baseline by a policy fingerprint.
|
|
51
|
+
|
|
52
|
+
The comparison also checks provider identity, measurement model (`measurementModel`),
|
|
53
|
+
compatibility key (`compatibilityKey`), task/contract/route bindings, source
|
|
54
|
+
material fingerprints, scan scope, provider config fingerprints, and optional
|
|
55
|
+
cycle/minimum conditions. Any mismatch is incomparable; it is never treated as a pass.
|
|
56
|
+
An explicit per-dimension failure fails the gate even when the aggregate signal improves.
|
|
57
|
+
Architecture-rule provenance is recorded separately and does not change Structural
|
|
58
|
+
Quality comparability when the measured source and provider scope are unchanged.
|
|
59
|
+
|
|
60
|
+
## 5. Modes
|
|
61
|
+
|
|
62
|
+
`structuralQuality` is absent by default for backward compatibility. When it is
|
|
63
|
+
present, the mode is exactly one of:
|
|
64
|
+
|
|
65
|
+
| Mode | Baseline and verification | Completion effect |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| `off` | No provider lookup or quality artifacts. | None. |
|
|
68
|
+
| `observe` | Records available comparisons and visible limitations. | Never blocks completion by itself. |
|
|
69
|
+
| `gate` | Requires a bound baseline before execution and a comparable current-cycle pass before completion. | Missing, stale, blocked, incomparable, or failed evidence blocks the quality requirement. |
|
|
70
|
+
|
|
71
|
+
An unavailable provider is `NOT_OBSERVED` in `observe` mode and `BLOCKED` in
|
|
72
|
+
`gate` mode. Neither mode turns unavailable evidence into `PASS`.
|
|
73
|
+
|
|
74
|
+
## 6. Configuration examples
|
|
75
|
+
|
|
76
|
+
ForgeLoop configuration lives in `.forgeloop/config.json`.
|
|
77
|
+
|
|
78
|
+
Recommended observation mode:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"schemaVersion": 1,
|
|
83
|
+
"protocolVersion": 1,
|
|
84
|
+
"complianceMode": "standard",
|
|
85
|
+
"structuralQuality": {
|
|
86
|
+
"mode": "observe",
|
|
87
|
+
"provider": "sentrux"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Strict gate mode with an intentional 50-point modularity budget:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"schemaVersion": 1,
|
|
97
|
+
"protocolVersion": 1,
|
|
98
|
+
"complianceMode": "strict",
|
|
99
|
+
"structuralQuality": {
|
|
100
|
+
"mode": "gate",
|
|
101
|
+
"provider": "sentrux",
|
|
102
|
+
"maxRegressionPoints": 0,
|
|
103
|
+
"dimensionBudgets": {
|
|
104
|
+
"modularity": 50,
|
|
105
|
+
"acyclicity": 0,
|
|
106
|
+
"depth": null,
|
|
107
|
+
"equality": null,
|
|
108
|
+
"redundancy": null
|
|
109
|
+
},
|
|
110
|
+
"forbidNewCycles": true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The provider name selects a registered provider only. Project configuration
|
|
116
|
+
cannot select an executable, shell, arbitrary arguments, score, baseline, or
|
|
117
|
+
provider-native command.
|
|
118
|
+
|
|
119
|
+
## 7. Baseline and verify commands
|
|
120
|
+
|
|
121
|
+
Capture the baseline after planning and before entering execution:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
forgeloop quality-baseline --task <task-id> --json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
An intentional replacement is allowed only before `EXECUTING` and retains
|
|
128
|
+
supersession evidence:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
forgeloop quality-baseline --task <task-id> --replace --json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
In `VERIFYING`, evaluate the current cycle:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
forgeloop quality-verify --task <task-id> --json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Inspect persisted evidence without starting a provider:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
forgeloop quality-status --task <task-id> --json
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The JSON envelopes preserve stable structural-quality error codes and never
|
|
147
|
+
include raw MCP streams.
|
|
148
|
+
|
|
149
|
+
## 8. Failure-to-diagnosis workflow
|
|
150
|
+
|
|
151
|
+
When a gate evaluation fails, ForgeLoop records a failed
|
|
152
|
+
`structural-quality` check with the evaluation artifact, bottleneck, all
|
|
153
|
+
root-cause deltas, failed policy conditions, and stable reason codes. It does
|
|
154
|
+
not invent a diagnosis. Follow the normal lifecycle:
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
VERIFYING
|
|
158
|
+
-> DIAGNOSING record an evidence-backed hypothesis
|
|
159
|
+
-> CORRECTING make the scoped correction
|
|
160
|
+
-> VERIFYING evaluate the new verification cycle
|
|
161
|
+
-> REVIEWING only after current-cycle evidence and other checks pass
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Use `forgeloop next --task <task-id> --json` at each boundary. A repeated
|
|
165
|
+
hypothesis without new information remains subject to ForgeLoop's existing
|
|
166
|
+
diagnosis and stall rules.
|
|
167
|
+
|
|
168
|
+
## 9. Optional bounded optimization
|
|
169
|
+
|
|
170
|
+
Optimization is advisory and disabled by default. If enabled with
|
|
171
|
+
`optimization.mode: "bounded"`, ForgeLoop may recommend at most two extra
|
|
172
|
+
evaluations in the current verification cycle. A passing baseline comparison
|
|
173
|
+
already satisfies completion; extra evaluations are never required.
|
|
174
|
+
|
|
175
|
+
The recommendation is suppressed when task scope is unavailable, stale, or
|
|
176
|
+
outside effective claims. A gain below `minGainPoints` converges the advisory
|
|
177
|
+
loop, and no optimization seeks a perfect `10000` score or widens the task.
|
|
178
|
+
|
|
179
|
+
## 10. Provider contract and measurement model
|
|
180
|
+
|
|
181
|
+
The public provider boundary is vendor-neutral:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
type StructuralQualityProviderInput = {
|
|
185
|
+
projectPath: string;
|
|
186
|
+
taskId: string;
|
|
187
|
+
timeoutMs: number;
|
|
188
|
+
maxOutputBytes: number;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
type StructuralQualityProvider = {
|
|
192
|
+
id: string;
|
|
193
|
+
detect?(input: StructuralQualityProviderInput): Promise<Detection>;
|
|
194
|
+
scan?(input: StructuralQualityProviderInput): Promise<SnapshotResult>;
|
|
195
|
+
observe?(input: StructuralQualityProviderInput): Promise<SnapshotResult>;
|
|
196
|
+
scopeBinding?(input: { projectPath: string }): Promise<ScopeBinding>;
|
|
197
|
+
};
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Providers declare `measurementModel` (such as `structural-root-causes-v1`) and
|
|
201
|
+
an optional `compatibilityKey` (such as `sentrux-structural-root-causes-v1`).
|
|
202
|
+
When baseline and evaluation share a compatibility key, non-breaking version
|
|
203
|
+
differences between provider releases compare cleanly. Sentrux compatibility
|
|
204
|
+
is explicit: the built-in adapter accepts only verified versions `0.5.5`,
|
|
205
|
+
`0.5.6`, and `0.5.7`; future or malformed versions fail closed until
|
|
206
|
+
explicitly verified.
|
|
207
|
+
|
|
208
|
+
Runtime hosts may inject a provider through `createForgeLoopContext`. Provider
|
|
209
|
+
IDs are lower-case stable names matching `^[a-z][a-z0-9-]{0,63}$`; the built-in
|
|
210
|
+
`sentrux` name is reserved. Provider output is untrusted until every field is
|
|
211
|
+
normalized, bounded, schema-validated, and semantically bound to the task.
|
|
212
|
+
|
|
213
|
+
## 11. Sentrux MCP adapter and tool arguments
|
|
214
|
+
|
|
215
|
+
Sentrux is not a ForgeLoop npm dependency. ForgeLoop never installs, upgrades,
|
|
216
|
+
or selects an arbitrary Sentrux executable. The built-in adapter invokes the
|
|
217
|
+
trusted command name `sentrux --mcp` through a shell-free local MCP process, requires
|
|
218
|
+
verified versions `0.5.5`, `0.5.6`, and `0.5.7`, and strictly conforms to Sentrux tool argument schemas:
|
|
219
|
+
|
|
220
|
+
- `scan`: `arguments: { path: "<project-path>" }`
|
|
221
|
+
- `health`: `arguments: {}`
|
|
222
|
+
|
|
223
|
+
Sentrux-specific configuration (such as `.sentrux/rules.toml`) is owned
|
|
224
|
+
exclusively by the Sentrux provider adapter via `scopeBinding()`. The adapter
|
|
225
|
+
records its SHA-256 as `scope.architectureRulesFingerprint` for provenance, but
|
|
226
|
+
the rules file is a separate Architecture Rules Sensor: changing it does not
|
|
227
|
+
make unchanged Structural Quality measurements incomparable. Generic provider
|
|
228
|
+
configuration remains a Structural Quality scope input and still invalidates
|
|
229
|
+
incompatible observations. The core resolver never scans for a rules file and
|
|
230
|
+
custom providers do not inherit this binding unless they explicitly expose their
|
|
231
|
+
own `scopeBinding()`.
|
|
232
|
+
|
|
233
|
+
If Sentrux is absent, preserve the resulting `NOT_OBSERVED` or `BLOCKED` state
|
|
234
|
+
and follow the configured mode. Install or upgrade Sentrux only through the
|
|
235
|
+
user's normal, separately authorized process.
|
|
236
|
+
|
|
237
|
+
The repository includes a real-provider interoperability scenario covering the
|
|
238
|
+
public baseline/verify path and an intentional `A -> B -> C -> A` cycle:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
node --test tests/real-sentrux-structural-quality.test.js
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The scenario runs when the user-managed `sentrux` executable reports a verified
|
|
245
|
+
version; environments without that external executable leave the scenario
|
|
246
|
+
unobserved rather than substituting a fake provider.
|
|
247
|
+
|
|
248
|
+
## 12. Sentrux Free versus optional diagnostics
|
|
249
|
+
|
|
250
|
+
The five scores, bottleneck, and the aggregate comparison are sufficient for a
|
|
251
|
+
structural-quality pass or fail. File-level diagnostics may be unavailable in
|
|
252
|
+
Sentrux Free. A missing diagnostics payload is therefore valid and remains
|
|
253
|
+
`null`; it does not weaken the score comparison and does not become a fake
|
|
254
|
+
diagnostic.
|
|
255
|
+
|
|
256
|
+
## 13. Freshness and optional observe actions
|
|
257
|
+
|
|
258
|
+
Baseline and observed `PASS`/`FAIL` artifacts must bind a stable source
|
|
259
|
+
fingerprint. Unreadable files, unsafe symlinks, source drift during a scan,
|
|
260
|
+
changed provider scope, and stale task bindings fail closed. `quality-status`,
|
|
261
|
+
`next`, recovery, provenance, and completion reuse the same freshness
|
|
262
|
+
validator and never promote a stale pass.
|
|
263
|
+
|
|
264
|
+
In `observe` mode, `next` may expose baseline or verification as optional
|
|
265
|
+
actions. These actions are advisory and do not spawn a provider from a
|
|
266
|
+
read-only status or next-action query.
|
|
267
|
+
|
|
268
|
+
## 14. Sentrux analytics are user choices
|
|
269
|
+
|
|
270
|
+
ForgeLoop does not change Sentrux's global analytics preference. If the
|
|
271
|
+
installed Sentrux version provides these commands, the user may inspect or
|
|
272
|
+
disable analytics independently:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
sentrux analytics status
|
|
276
|
+
sentrux analytics off
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Those commands are outside ForgeLoop evidence and should be run only with the
|
|
280
|
+
user's own authorization.
|
|
281
|
+
|
|
282
|
+
## 15. CI example
|
|
283
|
+
|
|
284
|
+
CI can run the same project-local commands after initializing the task and
|
|
285
|
+
configuring the provider on the runner:
|
|
286
|
+
|
|
287
|
+
```yaml
|
|
288
|
+
steps:
|
|
289
|
+
- run: forgeloop preflight --task $FORGELOOP_TASK --json
|
|
290
|
+
- run: forgeloop quality-baseline --task $FORGELOOP_TASK --json
|
|
291
|
+
- run: forgeloop advance --task $FORGELOOP_TASK --to EXECUTING --json
|
|
292
|
+
- run: forgeloop advance --task $FORGELOOP_TASK --to VERIFYING --json
|
|
293
|
+
- run: forgeloop quality-verify --task $FORGELOOP_TASK --json
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Provider installation, runner identity, and remote publication are separate
|
|
297
|
+
CI evidence. A green local or CI quality command does not imply a merge,
|
|
298
|
+
publication, or deployment.
|
|
299
|
+
|
|
300
|
+
## 16. Artifacts, locking, and projection reconciliation
|
|
301
|
+
|
|
302
|
+
Quality artifacts are task-owned and have no mutable `latest.json`:
|
|
303
|
+
|
|
304
|
+
```text
|
|
305
|
+
.forgeloop/task-state/<taskKey>/structural-quality/
|
|
306
|
+
baseline.json
|
|
307
|
+
evaluations/
|
|
308
|
+
cycle-<cycle>-attempt-<attempt>.json
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
The baseline is immutable after `EXECUTING`. External provider scans execute
|
|
312
|
+
outside the task mutation lock to prevent starvation of concurrent operations.
|
|
313
|
+
Pre-scan and post-scan source material fingerprints ensure observations are
|
|
314
|
+
stable against mid-scan source drift (`E_STRUCTURAL_QUALITY_SOURCE_DRIFT`).
|
|
315
|
+
Provider-owned `.sentrux` configuration is excluded from source material and
|
|
316
|
+
is handled only by the Sentrux scope binding. Source symlinks are rejected by
|
|
317
|
+
the fail-closed fingerprint policy. Rules provenance is retained in the scope,
|
|
318
|
+
but is not folded into the Structural Quality comparison fingerprint.
|
|
319
|
+
If an evaluation artifact was committed but check projection was interrupted,
|
|
320
|
+
subsequent verification retries automatically reconcile and repair the canonical
|
|
321
|
+
receipt check without rescanning or incrementing attempt counts.
|
|
322
|
+
|
|
323
|
+
Portable bundles include the baseline and evaluations required for audit.
|
|
324
|
+
Bundle readers validate typed artifacts and fingerprints without rescanning
|
|
325
|
+
the project or requiring Sentrux.
|
|
326
|
+
|
|
327
|
+
## 17. Error-code troubleshooting table
|
|
328
|
+
|
|
329
|
+
| Code | Meaning | First safe action |
|
|
330
|
+
| --- | --- | --- |
|
|
331
|
+
| `E_STRUCTURAL_QUALITY_CONFIGURATION_INVALID` | The structural-quality configuration is malformed or outside policy limits. | Correct `.forgeloop/config.json`, then rerun `preflight`. |
|
|
332
|
+
| `E_STRUCTURAL_QUALITY_PROVIDER_INVALID` | A provider contract or normalized observation is invalid. | Inspect provider integration and rerun with the same task; do not promote the observation. |
|
|
333
|
+
| `E_STRUCTURAL_QUALITY_PROVIDER_UNAVAILABLE` | The configured provider cannot be detected. | In observe mode continue with the limitation; in gate mode make the user-managed provider available. |
|
|
334
|
+
| `E_STRUCTURAL_QUALITY_PROVIDER_VERSION_UNSUPPORTED` | The provider is older than the supported contract. | Use a user-authorized supported provider version. |
|
|
335
|
+
| `E_STRUCTURAL_QUALITY_PROVIDER_PROTOCOL_INVALID` | MCP initialization, tool discovery, or response protocol is invalid. | Inspect the provider installation and keep the evidence blocked. |
|
|
336
|
+
| `E_STRUCTURAL_QUALITY_PROVIDER_TOOL_CONTRACT_INVALID` | The provider tool schemas do not expose required argument definitions. | Ensure provider exposes valid `scan` and `health` MCP tool argument schemas. |
|
|
337
|
+
| `E_STRUCTURAL_QUALITY_SCAN_FAILED` | The provider scan failed. | Diagnose the provider failure; never treat it as a pass. |
|
|
338
|
+
| `E_STRUCTURAL_QUALITY_TIMEOUT` | The bounded provider deadline expired. | Inspect provider health and rerun only after the cause is understood. |
|
|
339
|
+
| `E_STRUCTURAL_QUALITY_OUTPUT_LIMIT` | Combined provider output exceeded the safety limit. | Reduce provider verbosity or repair the provider; do not persist partial output. |
|
|
340
|
+
| `E_STRUCTURAL_QUALITY_BASELINE_MISSING` | A gate task has no valid baseline. | Capture it in `PLANNED` after a valid preflight checkpoint. |
|
|
341
|
+
| `E_STRUCTURAL_QUALITY_BASELINE_EXISTS` | A different baseline already exists. | Keep the immutable baseline, or use authorized `--replace` before execution. |
|
|
342
|
+
| `E_STRUCTURAL_QUALITY_BASELINE_PHASE_INVALID` | Baseline replacement was attempted after execution began. | Repair against the existing baseline in a new verification cycle. |
|
|
343
|
+
| `E_STRUCTURAL_QUALITY_BASELINE_BINDING_MISMATCH` | Baseline bindings no longer match the task inputs. | Inspect policy, route, provider scope, and source drift; do not bypass the binding. |
|
|
344
|
+
| `E_STRUCTURAL_QUALITY_EVALUATION_INCOMPARABLE` | Current and baseline observations cannot be compared. | Resolve provider/version/policy/provider-scope drift and verify again; architecture-rule changes alone are informational. |
|
|
345
|
+
| `E_STRUCTURAL_QUALITY_MEASUREMENT_MODEL_MISMATCH` | Measurement models differ between baseline and evaluation. | Ensure baseline and evaluation share a compatible measurement model. |
|
|
346
|
+
| `E_STRUCTURAL_QUALITY_EVIDENCE_STALE` | A quality check is from an old cycle or points to stale evidence. | Run the current-cycle verification and record its canonical check. |
|
|
347
|
+
| `E_STRUCTURAL_QUALITY_SOURCE_DRIFT` | Source material was mutated during provider observation. | Ensure worktree remains stable during quality scans and rerun verification. |
|
|
348
|
+
| `E_STRUCTURAL_QUALITY_OBSERVATION_EPOCH_STALE` | Task state epoch changed during observation. | Re-run quality verification under the active task epoch. |
|
|
349
|
+
| `E_STRUCTURAL_QUALITY_PROJECTION_INCOMPLETE` | Check projection was incomplete. | Re-run quality verification to reconcile the canonical check from the evaluation. |
|
|
350
|
+
| `E_STRUCTURAL_QUALITY_REGRESSION` | The configured aggregate, dimension, cycle, or minimum policy failed. | Record a diagnosis from the evaluation evidence and correct the scoped code. |
|