@cassiomc1/forgeloop 1.13.0 → 2.0.0-rc.2
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 +8 -0
- package/CONTRIBUTING.md +11 -7
- package/DOCS_INDEX.md +37 -4
- package/ENG/c-development-eng.md +2 -2
- package/ENG/cpp-development-eng.md +2 -2
- package/ENG/dotnet-aspnetcore-development-eng.md +7 -1
- package/ENG/flutter-development-eng.md +4 -2
- package/ENG/go-development-eng.md +2 -2
- package/ENG/java-development-eng.md +3 -3
- package/ENG/nodejs-backend-development-eng.md +10 -6
- package/ENG/php-development-eng.md +3 -3
- package/ENG/python-development-eng.md +205 -0
- package/ENG/rust-development-eng.md +42 -1
- package/ENG/sec-code-eng.md +7 -7
- package/ENG/sql-development-eng.md +4 -4
- package/ENG/swift-development-eng.md +5 -4
- package/ENG/test-code-eng.md +1 -1
- package/ENG/typescript-development-eng.md +4 -4
- package/EXECUTION_STATE.md +12 -0
- package/GUIDE_ROUTER.md +6 -0
- package/LICENSE +133 -21
- package/LOOP_ENGINEERING.md +28 -2
- package/LOOP_SYSTEM_DESIGN.md +10 -10
- package/ORCHESTRATOR_INTEGRATION.md +9 -5
- package/PROTOCOL_INTEGRATION.md +55 -2
- package/README.md +63 -59
- package/TERMINOLOGY.md +2 -0
- package/THIRD_PARTY_NOTICES.md +3 -4
- package/THREAT_MODEL.md +140 -1
- package/completions/_forgeloop +29 -3
- package/completions/forgeloop.bash +55 -3
- package/completions/forgeloop.fish +183 -1
- package/docs/ADVISORY_CONTEXT.md +25 -0
- package/docs/AGENT_BROWSER_ADAPTER.md +81 -0
- package/docs/AGENT_BROWSER_VERIFICATION.md +6 -0
- package/docs/AGENT_PROTOCOL_SUMMARY.md +74 -39
- package/docs/AGENT_SKILL.md +66 -0
- package/docs/ARTIFACT_REFERENCE.md +171 -35
- package/docs/AUDIT_UX.md +46 -0
- package/docs/BROWSER_VERIFICATION.md +136 -0
- package/docs/CLI_REFERENCE.md +512 -8
- package/docs/CODE_ATTESTATION.md +2 -2
- package/docs/DOCUMENTATION_GUIDE.md +34 -11
- package/docs/GETTING_STARTED.md +3 -3
- package/docs/JEV_BENCHMARKS.md +31 -0
- package/docs/MODEL_ROUTING.md +37 -0
- package/docs/OPENSRC_ADAPTER.md +241 -0
- package/docs/PACKAGE_CONTENTS.md +46 -18
- package/docs/PROVIDERS.md +126 -0
- package/docs/PROVIDER_ARCHITECTURE.md +199 -0
- package/docs/RECIPES.md +9 -0
- package/docs/RELEASE_CHECKLIST.md +116 -12
- package/docs/SECURITY_REVIEW.md +71 -0
- package/docs/SELF_HOSTED_TESTS.md +121 -0
- package/docs/SEMANTIC_DECISION_PLANE.md +71 -0
- package/docs/TEST_INTELLIGENCE.md +29 -0
- package/docs/TEST_PRUNING.md +14 -0
- package/docs/TROUBLESHOOTING.md +198 -1
- package/docs/UNIVERSAL_INTEGRATION.md +31 -0
- package/docs/assets/diagrams/forgeloop-code-attestation-flow.html +2 -2
- package/docs/assets/diagrams/forgeloop-code-attestation-flow.receipt.json +5 -5
- package/docs/assets/diagrams/forgeloop-code-attestation-flow.svg +1 -1
- package/docs/assets/diagrams/forgeloop-engineering-flow.html +39 -26
- package/docs/assets/diagrams/forgeloop-engineering-flow.receipt.json +6 -6
- package/docs/assets/diagrams/forgeloop-engineering-flow.svg +26 -26
- package/docs/assets/diagrams/forgeloop-verification-trust-flow.html +2 -1
- package/docs/assets/diagrams/forgeloop-verification-trust-flow.receipt.json +5 -5
- package/docs/assets/diagrams/forgeloop-verification-trust-flow.svg +1 -1
- package/docs/diagrams/README.md +13 -9
- package/docs/diagrams/forgeloop-code-attestation-flow.workflow.json +1 -1
- package/docs/diagrams/forgeloop-engineering-flow.workflow.json +24 -19
- package/docs/diagrams/forgeloop-verification-trust-flow.workflow.json +1 -0
- package/docs/diagrams/reviews/forgeloop-code-attestation-flow.review.json +4 -4
- package/docs/diagrams/reviews/forgeloop-engineering-flow.review.json +4 -4
- package/docs/diagrams/reviews/forgeloop-verification-trust-flow.review.json +4 -4
- package/docs/documentation-manifest.json +774 -16
- package/docs/protocol-requirements.json +24 -0
- package/package.json +43 -11
- package/schemas/config.schema.json +14 -0
- package/schemas/context-plan.schema.json +18 -0
- package/schemas/semantic-decision.schema.json +46 -0
- package/schemas/task-bundle.schema.json +7 -2
- package/schemas/test-utility.schema.json +44 -0
- package/scripts/CI_VALIDATORS.md +6 -6
- package/scripts/benchmark-jev.mjs +5 -0
- package/scripts/benchmark-test-intelligence.mjs +4 -0
- package/scripts/generate-agent-protocol-summary.mjs +6 -3
- package/scripts/generate-forgeloop-skill.mjs +133 -0
- package/scripts/jev-smoke.mjs +19 -0
- package/scripts/run-mcp-clean-tests.mjs +30 -0
- package/skills/forgeloop/README.md +9 -0
- package/skills/forgeloop/SKILL.md +77 -0
- package/skills/forgeloop/references/lifecycle.md +9 -0
- package/skills/forgeloop/references/recovery.md +7 -0
- package/skills/forgeloop/references/verification.md +7 -0
- package/src/adapters/agent-browser/assertions.js +47 -0
- package/src/adapters/agent-browser/commands.js +54 -0
- package/src/adapters/agent-browser/index.js +3 -0
- package/src/adapters/agent-browser/locator.js +40 -0
- package/src/adapters/agent-browser/process.js +215 -0
- package/src/adapters/agent-browser/provider.js +316 -0
- package/src/adapters/emulated-services/constants.js +24 -0
- package/src/adapters/emulated-services/index.js +7 -0
- package/src/adapters/emulated-services/process.js +162 -0
- package/src/adapters/emulated-services/provider.js +289 -0
- package/src/adapters/opensrc/normalize.js +90 -0
- package/src/adapters/opensrc/process.js +248 -0
- package/src/adapters/opensrc/provider.js +338 -0
- package/src/adapters/opensrc/search.js +264 -0
- package/src/adapters/temporary-paths.js +18 -0
- package/src/adapters/typesafe/client.js +28 -0
- package/src/adapters/typesafe/engine.js +63 -0
- package/src/adapters/typesafe/normalize.js +41 -0
- package/src/cli.js +218 -174
- package/src/commands/action-show.js +5 -2
- package/src/commands/advance.js +5 -1
- package/src/commands/baseline.js +13 -11
- package/src/commands/checkpoint-revalidate.js +192 -0
- package/src/commands/complete.js +19 -3
- package/src/commands/context-plan.js +38 -0
- package/src/commands/contract-create.js +266 -0
- package/src/commands/contract-revise.js +236 -0
- package/src/commands/decision-show.js +14 -0
- package/src/commands/decision-status.js +22 -0
- package/src/commands/discover.js +41 -0
- package/src/commands/doctor.js +51 -13
- package/src/commands/gate-record.js +194 -0
- package/src/commands/gate-revalidate.js +135 -0
- package/src/commands/handoff-list.js +6 -1
- package/src/commands/handoff-show.js +6 -1
- package/src/commands/migrate-protocol.js +2 -2
- package/src/commands/model-route.js +40 -0
- package/src/commands/next.js +7 -1
- package/src/commands/policy-diff.js +25 -4
- package/src/commands/progress.js +17 -11
- package/src/commands/record-diagnosis.js +3 -0
- package/src/commands/route.js +146 -18
- package/src/commands/semantic-plan.js +41 -0
- package/src/commands/status.js +6 -1
- package/src/commands/storage-backup.js +15 -0
- package/src/commands/storage-migrate.js +5 -0
- package/src/commands/storage-migration-resume.js +5 -0
- package/src/commands/storage-migration-status.js +44 -0
- package/src/commands/storage-restore-resume.js +7 -0
- package/src/commands/storage-restore.js +8 -0
- package/src/commands/task-abandon.js +224 -0
- package/src/commands/task-list.js +8 -43
- package/src/commands/task-migrate-contract-bootstrap-repair.js +288 -0
- package/src/commands/task-migrate.js +3 -3
- package/src/commands/task-recover.js +10 -2
- package/src/commands/task-repair-contract-bootstrap.js +263 -0
- package/src/commands/task-scope.js +18 -2
- package/src/commands/task-show.js +16 -2
- package/src/commands/test-inventory.js +5 -0
- package/src/commands/test-prune-plan.js +5 -0
- package/src/commands/test-prune-probe.js +5 -0
- package/src/commands/test-utility.js +5 -0
- package/src/commands/validate-protocol.js +39 -15
- package/src/commands/validate-receipt.js +8 -1
- package/src/config/guides.json +4 -0
- package/src/core/action-ledger-projection.js +10 -3
- package/src/core/actions.js +38 -75
- package/src/core/activation.js +11 -3
- package/src/core/approvals.js +17 -51
- package/src/core/artifact-registry.js +83 -2
- package/src/core/artifacts.js +81 -27
- package/src/core/attachment-paths.js +45 -0
- package/src/core/attestation-coverage.js +6 -1
- package/src/core/attestation-verifier.js +21 -2
- package/src/core/attestation.js +17 -6
- package/src/core/audit-ux.js +514 -0
- package/src/core/audit.js +6 -1
- package/src/core/browser-verification/constants.js +149 -0
- package/src/core/browser-verification/normalize.js +254 -0
- package/src/core/browser-verification/provider.js +519 -0
- package/src/core/browser-verification/service.js +115 -0
- package/src/core/bundles.js +160 -66
- package/src/core/checkpoint-revalidation.js +321 -0
- package/src/core/cli-command-definitions.js +350 -7
- package/src/core/code-manifest.js +9 -3
- package/src/core/command-executors.js +274 -108
- package/src/core/command-input.js +136 -44
- package/src/core/completion-artifacts.js +85 -34
- package/src/core/completion-ownership.js +19 -8
- package/src/core/completion-recovery-rebind.js +11 -1
- package/src/core/completion.js +64 -15
- package/src/core/config.js +3 -0
- package/src/core/conformance.js +2 -1
- package/src/core/context-compiler/budget.js +9 -0
- package/src/core/context-compiler/candidates.js +39 -0
- package/src/core/context-compiler/compiler.js +63 -0
- package/src/core/context-compiler/fingerprint.js +11 -0
- package/src/core/context-compiler/policy.js +13 -0
- package/src/core/context-compiler/result.js +23 -0
- package/src/core/continuity-lint.js +13 -2
- package/src/core/continuity-reconciliation.js +16 -3
- package/src/core/continuity.js +16 -8
- package/src/core/contract-bootstrap-recovery.js +656 -0
- package/src/core/contract-revision.js +209 -0
- package/src/core/decision/artifact.js +70 -0
- package/src/core/decision/benchmarks.js +103 -0
- package/src/core/decision/cache.js +27 -0
- package/src/core/decision/constants.js +58 -0
- package/src/core/decision/cutover.js +34 -0
- package/src/core/decision/engine.js +22 -0
- package/src/core/decision/errors.js +68 -0
- package/src/core/decision/events.js +104 -0
- package/src/core/decision/freshness.js +19 -0
- package/src/core/decision/normalizers/index.js +115 -0
- package/src/core/decision/policy.js +18 -0
- package/src/core/decision/projection.js +16 -0
- package/src/core/decision/question-registry.js +201 -0
- package/src/core/decision/request.js +26 -0
- package/src/core/decision/resolver.js +138 -0
- package/src/core/decision/result.js +58 -0
- package/src/core/decision/service.js +181 -0
- package/src/core/decision/state-builder.js +65 -0
- package/src/core/decision/task-bindings.js +35 -0
- package/src/core/decision/test-provider.js +32 -0
- package/src/core/decision/thresholds.js +15 -0
- package/src/core/diagnosis-model.js +11 -0
- package/src/core/diagnosis.js +10 -1
- package/src/core/diagnostic-projection.js +29 -12
- package/src/core/diagnostic-record.js +28 -3
- package/src/core/efficiency.js +6 -1
- package/src/core/error-codes.js +278 -0
- package/src/core/events.js +535 -147
- package/src/core/evidence-readiness.js +9 -0
- package/src/core/execution-prerequisites.js +36 -13
- package/src/core/execution-profile.js +63 -38
- package/src/core/execution.js +26 -40
- package/src/core/filesystem.js +11 -0
- package/src/core/gate-artifact.js +105 -19
- package/src/core/gate-provenance.js +125 -0
- package/src/core/handoff.js +26 -14
- package/src/core/history.js +39 -35
- package/src/core/hypothesis-projection.js +32 -0
- package/src/core/information-gain-projection.js +104 -100
- package/src/core/inspect.js +12 -3
- package/src/core/integration-invocation-policy.js +37 -4
- package/src/core/integration-resources.js +119 -87
- package/src/core/ledger-event-collection.js +189 -0
- package/src/core/ledger-relations.js +23 -0
- package/src/core/model-router/constants.js +10 -0
- package/src/core/model-router/policy.js +103 -0
- package/src/core/model-router/router.js +37 -0
- package/src/core/native-storage.js +12 -0
- package/src/core/next-action-continuity.js +31 -9
- package/src/core/next-action-model.js +58 -0
- package/src/core/next-action-phases.js +131 -43
- package/src/core/next-action-refresh.js +43 -9
- package/src/core/next-action-review-phase.js +9 -4
- package/src/core/next-action-verification-phase.js +2 -1
- package/src/core/next-action.js +56 -9
- package/src/core/phase.js +266 -103
- package/src/core/policy-engine.js +12 -13
- package/src/core/preflight-consistency.js +89 -62
- package/src/core/preflight-loaders.js +48 -9
- package/src/core/preflight-model.js +6 -1
- package/src/core/preflight.js +29 -12
- package/src/core/progress.js +21 -10
- package/src/core/protocol-info.js +68 -0
- package/src/core/protocol-migration.js +7 -6
- package/src/core/protocol.js +20 -0
- package/src/core/reconcile-closure.js +281 -67
- package/src/core/recovery-history.js +67 -47
- package/src/core/reflection.js +72 -77
- package/src/core/responsibility.js +25 -13
- package/src/core/resumability.js +154 -44
- package/src/core/route-artifact.js +28 -4
- package/src/core/router.js +67 -1
- package/src/core/runtime-context.js +123 -61
- package/src/core/schema-validation.js +11 -3
- package/src/core/security-review/constants.js +64 -0
- package/src/core/security-review/normalize.js +245 -0
- package/src/core/security-review/provider.js +204 -0
- package/src/core/security-review/service.js +134 -0
- package/src/core/semantic-planning/constants.js +19 -0
- package/src/core/semantic-planning/projection.js +94 -0
- package/src/core/semantic-planning/service.js +15 -0
- package/src/core/settlement.js +12 -1
- package/src/core/signing/bundle-file.js +53 -0
- package/src/core/signing/bundle-reference.js +15 -0
- package/src/core/signing/sigstore.js +60 -33
- package/src/core/signing/statement-file.js +27 -0
- package/src/core/sources.js +37 -0
- package/src/core/storage-runtime-registry.js +41 -0
- package/src/core/structural-quality/artifacts.js +20 -14
- package/src/core/structural-quality/service.js +81 -56
- package/src/core/target-layout.js +1 -1
- package/src/core/task-claim-state.js +249 -15
- package/src/core/task-command.js +21 -1
- package/src/core/task-conflict-inspection.js +133 -102
- package/src/core/task-descriptor.js +29 -22
- package/src/core/task-discovery.js +288 -90
- package/src/core/task-lock.js +66 -306
- package/src/core/task-migration-validation.js +5 -5
- package/src/core/task-migration.js +17 -287
- package/src/core/task-paths.js +13 -0
- package/src/core/task-recovery.js +1 -0
- package/src/core/task-snapshot.js +51 -8
- package/src/core/task-storage-migration.js +18 -0
- package/src/core/templates.js +23 -8
- package/src/core/test-intelligence/benchmarks.js +68 -0
- package/src/core/test-intelligence/inventory.js +73 -0
- package/src/core/test-intelligence/prune.js +94 -0
- package/src/core/test-intelligence/semantic-state.js +15 -0
- package/src/core/test-intelligence/service.js +40 -0
- package/src/core/test-intelligence/utility.js +50 -0
- package/src/core/trace.js +164 -105
- package/src/core/trajectory-evaluation.js +15 -3
- package/src/core/trajectory-metrics.js +47 -32
- package/src/core/transaction.js +16 -287
- package/src/core/verification-scope.js +20 -12
- package/src/core/work-state.js +100 -59
- package/src/integration.d.ts +492 -0
- package/src/integration.js +54 -0
- package/src/providers/README.md +47 -0
- package/src/providers/capabilities.js +46 -0
- package/src/providers/errors.js +15 -0
- package/src/providers/index.js +29 -0
- package/src/providers/json-snapshot.js +105 -0
- package/src/providers/registry.js +152 -0
- package/src/repository-index/binary-manager.js +7 -5
- package/src/storage/artifact-bytes.js +22 -0
- package/src/storage/attachment-binding.js +11 -0
- package/src/storage/attachment-files.js +82 -0
- package/src/storage/attachment-references.js +36 -0
- package/src/storage/backup.js +53 -0
- package/src/storage/capabilities.js +31 -0
- package/src/storage/connection-owner.js +119 -0
- package/src/storage/connection.js +376 -0
- package/src/storage/existing-project-scope.js +45 -0
- package/src/storage/export-destination.js +44 -0
- package/src/storage/exporter.js +284 -0
- package/src/storage/file-durability.js +46 -0
- package/src/storage/importer.js +461 -0
- package/src/storage/index.js +74 -0
- package/src/storage/leases.js +63 -0
- package/src/storage/ledger-event-snapshot.js +150 -0
- package/src/storage/ledger-relations.js +220 -0
- package/src/storage/legacy-maintenance-boundary.js +18 -0
- package/src/storage/legacy-signature.js +115 -0
- package/src/storage/maintenance-handoff.js +129 -0
- package/src/storage/maintenance-owner.js +42 -0
- package/src/storage/maintenance.js +310 -0
- package/src/storage/metadata-json.js +35 -0
- package/src/storage/migration-activate.js +59 -0
- package/src/storage/migration-archive.js +57 -0
- package/src/storage/migration-attachment-root.js +61 -0
- package/src/storage/migration-candidate.js +398 -0
- package/src/storage/migration-publication.js +143 -0
- package/src/storage/migration-rollback-admission.js +54 -0
- package/src/storage/migration-rollback-preparation.js +132 -0
- package/src/storage/migration-rollback-publication.js +183 -0
- package/src/storage/migration-rollback-release.js +66 -0
- package/src/storage/migration-rollback-source-stage.js +103 -0
- package/src/storage/migration-rollback.js +43 -0
- package/src/storage/migration-source-partition.js +56 -0
- package/src/storage/migration-source.js +255 -0
- package/src/storage/migration-terminal.js +39 -0
- package/src/storage/migration-validation.js +75 -0
- package/src/storage/migration.js +43 -0
- package/src/storage/operational-attachments.js +49 -0
- package/src/storage/operational-context.js +50 -0
- package/src/storage/project-backup.js +98 -0
- package/src/storage/project-bootstrap.js +24 -0
- package/src/storage/project-boundary.js +79 -0
- package/src/storage/project-read-snapshot.js +18 -0
- package/src/storage/project-replacement.js +137 -0
- package/src/storage/project-restore.js +203 -0
- package/src/storage/record-definitions.js +45 -0
- package/src/storage/repository.js +507 -0
- package/src/storage/restore-journal.js +62 -0
- package/src/storage/restore-layout.js +30 -0
- package/src/storage/restore-preparation.js +84 -0
- package/src/storage/restore-replacement-archive.js +162 -0
- package/src/storage/restore-replacement-owner.js +31 -0
- package/src/storage/restore-replacement-preparation.js +128 -0
- package/src/storage/restore-replacement.js +142 -0
- package/src/storage/restore-terminal.js +32 -0
- package/src/storage/runtime.js +31 -0
- package/src/storage/schema.js +214 -0
- package/src/storage/singleton-import.js +84 -0
- package/src/storage/snapshot-continuity.js +16 -0
- package/src/storage/snapshot.js +36 -0
- package/src/storage/storage-marker.js +79 -0
- package/src/storage/task-guards.js +107 -0
- package/src/storage/topology.js +42 -0
- package/src/storage/transaction.js +179 -0
- package/src/storage/unit-of-work.js +663 -0
- package/src/storage/windows-process-incarnation.js +206 -0
- package/.forgeloop/forgeloop.gitignore +0 -4
- package/LICENSE-DOCS.md +0 -13
- package/src/core/transaction-maintenance.js +0 -70
package/src/core/completion.js
CHANGED
|
@@ -10,7 +10,7 @@ import { completionRelationshipErrors } from "./completion-relationships.js";
|
|
|
10
10
|
import { assertSafePath, ensureWithin, fileExists } from "./filesystem.js";
|
|
11
11
|
import { evaluateStartExecutionPrerequisites, hasExecutionStarted } from "./execution-prerequisites.js";
|
|
12
12
|
import { isRecoverableCompletionEvidenceCode } from "./completion-recovery.js";
|
|
13
|
-
import { evaluateTerminalRequirements } from "./evidence-readiness.js";
|
|
13
|
+
import { evaluateTerminalRequirements, terminalRequirementsForContract } from "./evidence-readiness.js";
|
|
14
14
|
import { PROJECT_ARTIFACT_PATHS, taskArtifactPath, taskCodeManifestPath } from "./task-paths.js";
|
|
15
15
|
import { detectPolicyCapability, evaluateTargetPolicy } from "./policy-engine.js";
|
|
16
16
|
import { listActions } from "./actions.js";
|
|
@@ -18,7 +18,9 @@ import { readConfig } from "./config.js";
|
|
|
18
18
|
import { resolveResponsibilityStatus } from "./responsibility.js";
|
|
19
19
|
import { createCodeManifest, readCodeManifest, validateCodeManifestBindings, writeCodeManifest } from "./code-manifest.js";
|
|
20
20
|
import { getTaskTransaction, withTaskTransaction } from "./transaction.js";
|
|
21
|
+
import { operationalArtifactExists } from "../storage/operational-context.js";
|
|
21
22
|
import { validateStructuralQualityCheckProvenance } from "./structural-quality/service.js";
|
|
23
|
+
import { withNativeReadScope } from "./native-storage.js";
|
|
22
24
|
|
|
23
25
|
async function attestationConfiguration(target, packageRoot, errors) {
|
|
24
26
|
try {
|
|
@@ -79,6 +81,12 @@ function issue(code, message, artifacts = [], details = {}) {
|
|
|
79
81
|
return { code, message, artifacts, ...details };
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
export function receiptReadFailure(error, relativePath) {
|
|
85
|
+
return error.taskIdentityMismatch
|
|
86
|
+
? issue("E_RECEIPT_TASK_MISMATCH", "Execution receipt does not belong to the current contract task", [relativePath])
|
|
87
|
+
: issue("E_RECEIPT_INVALID", `Repair or remove the invalid execution receipt before continuing: ${error.message}`, [relativePath]);
|
|
88
|
+
}
|
|
89
|
+
|
|
82
90
|
export function completionIdentityErrors({ contract, state, receipt } = {}) {
|
|
83
91
|
return completionRelationshipErrors({ contract, state, receipt })
|
|
84
92
|
.filter((error) => ["E_STATE_TASK_MISMATCH", "E_RECEIPT_TASK_MISMATCH"].includes(error.code));
|
|
@@ -226,6 +234,10 @@ async function loadRequired(readArtifact, errorCode, errorMessage, artifacts, er
|
|
|
226
234
|
try {
|
|
227
235
|
return await readArtifact();
|
|
228
236
|
} catch (error) {
|
|
237
|
+
if (errorCode === "E_RECEIPT_MISSING" && error.taskIdentityMismatch) {
|
|
238
|
+
errors.push(receiptReadFailure(error, artifacts[0]));
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
229
241
|
if (error.code === "ARTIFACT_MISSING") {
|
|
230
242
|
errors.push(issue(errorCode, errorMessage, artifacts));
|
|
231
243
|
return null;
|
|
@@ -235,6 +247,19 @@ async function loadRequired(readArtifact, errorCode, errorMessage, artifacts, er
|
|
|
235
247
|
}
|
|
236
248
|
}
|
|
237
249
|
|
|
250
|
+
async function loadCompletionActions(target, packageRoot, taskId, errors) {
|
|
251
|
+
const { evaluateRequiredActionReadiness } = await import("./action-readiness.js");
|
|
252
|
+
const evidence = taskId ? await loadRequired(async () => ({
|
|
253
|
+
actions: await listActions(target, { packageRoot, taskId }),
|
|
254
|
+
readiness: await evaluateRequiredActionReadiness({ target, packageRoot, taskId }),
|
|
255
|
+
}), "E_ACTION_INVALID", "Durable action evidence is not available", [taskArtifactPath(taskId, "actions")], errors) : null;
|
|
256
|
+
return {
|
|
257
|
+
actions: evidence?.actions ?? [],
|
|
258
|
+
readiness: evidence?.readiness
|
|
259
|
+
?? { total: 0, satisfied: 0, unresolved: 0, ambiguous: 0, failed: 0, untrusted: 0, actions: [] },
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
238
263
|
function publicationStatus(receipt) {
|
|
239
264
|
if (receipt.publicationStatus) return receipt.publicationStatus;
|
|
240
265
|
if (receipt.publication?.deployed) return "deployed";
|
|
@@ -246,9 +271,10 @@ function publicationStatus(receipt) {
|
|
|
246
271
|
async function validateLedger(target, scopedTaskId, contractTaskId, state, errors, packageRoot, options = {}) {
|
|
247
272
|
const eventsRel = options.eventsPath ?? (scopedTaskId ? taskArtifactPath(scopedTaskId, "events") : ARTIFACT_PATHS.events);
|
|
248
273
|
const stateRel = options.statePath ?? (scopedTaskId ? taskArtifactPath(scopedTaskId, "state") : ARTIFACT_PATHS.state);
|
|
249
|
-
|
|
274
|
+
const operationalExists = operationalArtifactExists(target, eventsRel);
|
|
275
|
+
if (operationalExists === null) await assertSafePath(target, eventsRel);
|
|
250
276
|
const eventsFilePath = ensureWithin(target, eventsRel);
|
|
251
|
-
if (!(await fileExists(eventsFilePath))) {
|
|
277
|
+
if (operationalExists === false || (operationalExists === null && !(await fileExists(eventsFilePath)))) {
|
|
252
278
|
errors.push(issue("E_PHASE_CHRONOLOGY_INVALID", "Protocol event ledger is required before completion", [eventsRel]));
|
|
253
279
|
return { valid: false, events: [], errors: [] };
|
|
254
280
|
}
|
|
@@ -286,6 +312,35 @@ export async function evaluateCompletion({
|
|
|
286
312
|
receiptPath = null,
|
|
287
313
|
eventsPath = null,
|
|
288
314
|
preflightPath = null,
|
|
315
|
+
} = {}) {
|
|
316
|
+
const options = { target, packageRoot, strict, authorityContext, runtimeContext, taskId, contractPath, routePath, statePath, receiptPath, eventsPath, preflightPath };
|
|
317
|
+
return withNativeReadScope(target, async () => evaluateSelectedCompletion(await resolveCompletionTaskOptions(options)));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
async function resolveCompletionTaskOptions(options) {
|
|
321
|
+
if (options.taskId) return options;
|
|
322
|
+
try {
|
|
323
|
+
const state = await readWorkState(options.target, { packageRoot: options.packageRoot, statePath: options.statePath });
|
|
324
|
+
return state ? { ...options, taskId: state.taskId } : options;
|
|
325
|
+
} catch {
|
|
326
|
+
// Preserve the evaluator's structured missing/invalid-state diagnostics.
|
|
327
|
+
return options;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async function evaluateSelectedCompletion({
|
|
332
|
+
target,
|
|
333
|
+
packageRoot,
|
|
334
|
+
strict = false,
|
|
335
|
+
authorityContext,
|
|
336
|
+
runtimeContext,
|
|
337
|
+
taskId = null,
|
|
338
|
+
contractPath = null,
|
|
339
|
+
routePath = null,
|
|
340
|
+
statePath = null,
|
|
341
|
+
receiptPath = null,
|
|
342
|
+
eventsPath = null,
|
|
343
|
+
preflightPath = null,
|
|
289
344
|
} = {}) {
|
|
290
345
|
const errors = [];
|
|
291
346
|
const preflight = await evaluatePreflight({ target, packageRoot, strict, taskId, contractPath, routePath, statePath });
|
|
@@ -500,12 +555,10 @@ export async function evaluateCompletion({
|
|
|
500
555
|
const publication = receiptValue ? publicationStatus(receiptValue) : "not-published";
|
|
501
556
|
|
|
502
557
|
if (contract) {
|
|
503
|
-
const allContractReqs = [
|
|
504
|
-
...(contract.value.verification ?? []),
|
|
505
|
-
...(contract.value.successCriteria ?? []),
|
|
506
|
-
];
|
|
507
558
|
const terminalEval = evaluateTerminalRequirements({
|
|
508
|
-
requirements:
|
|
559
|
+
requirements: terminalRequirementsForContract(contract.value, {
|
|
560
|
+
additionalEvidence: preflight.policy?.requiredEvidence ?? [],
|
|
561
|
+
}),
|
|
509
562
|
receipt: receiptValue,
|
|
510
563
|
});
|
|
511
564
|
for (const termErr of terminalEval.errors) {
|
|
@@ -559,19 +612,14 @@ export async function evaluateCompletion({
|
|
|
559
612
|
}
|
|
560
613
|
|
|
561
614
|
const actionTaskId = contract?.value?.taskId ?? taskId;
|
|
562
|
-
|
|
563
|
-
? await listActions(target, { packageRoot, taskId: actionTaskId })
|
|
564
|
-
: [];
|
|
615
|
+
|
|
565
616
|
const contractRequirements = new Set([
|
|
566
617
|
...(contract?.value?.verification ?? []), ...(contract?.value?.successCriteria ?? []),
|
|
567
618
|
]);
|
|
568
619
|
// Completion truth consumes the canonical action-readiness projection, not
|
|
569
620
|
// raw state labels: a forged VERIFIED label can never satisfy a required
|
|
570
621
|
// action (INV-VERIFY-02).
|
|
571
|
-
const {
|
|
572
|
-
const requiredActionReadiness = actionTaskId
|
|
573
|
-
? await evaluateRequiredActionReadiness({ target, packageRoot, taskId: actionTaskId })
|
|
574
|
-
: { total: 0, satisfied: 0, unresolved: 0, ambiguous: 0, failed: 0, untrusted: 0, actions: [] };
|
|
622
|
+
const { actions: durableActions, readiness: requiredActionReadiness } = await loadCompletionActions(target, packageRoot, actionTaskId, errors);
|
|
575
623
|
for (const readiness of requiredActionReadiness.actions) {
|
|
576
624
|
if (readiness.status === "SATISFIED") continue;
|
|
577
625
|
const action = durableActions.find((candidate) => candidate.actionId === readiness.actionId);
|
|
@@ -855,6 +903,7 @@ async function runCompleteInternal({
|
|
|
855
903
|
}
|
|
856
904
|
|
|
857
905
|
export async function runComplete(options = {}) {
|
|
906
|
+
options = await resolveCompletionTaskOptions(options);
|
|
858
907
|
const taskId = options.taskId ?? null;
|
|
859
908
|
if (options.persist !== false && taskId && !(await getTaskTransaction(options.target))) {
|
|
860
909
|
return withTaskTransaction({
|
package/src/core/config.js
CHANGED
|
@@ -4,6 +4,7 @@ import { E_ATTESTATION_CONFIGURATION_INVALID } from "./error-codes.js";
|
|
|
4
4
|
import { normalizeVerificationConfiguration } from "./verification-scope-capability.js";
|
|
5
5
|
import { EXECUTION_PROFILE_REQUESTS } from "./execution-profile.js";
|
|
6
6
|
import { normalizeStructuralQualityConfig } from "./structural-quality/policy.js";
|
|
7
|
+
import { normalizeDecisionPolicy } from "./decision/policy.js";
|
|
7
8
|
|
|
8
9
|
export const CONFIG_SCHEMA_VERSION = 1;
|
|
9
10
|
export const COMPLIANCE_MODES = Object.freeze(["advisory", "standard", "strict"]);
|
|
@@ -82,6 +83,7 @@ export function createConfig(input = {}) {
|
|
|
82
83
|
executionProfile = input.executionProfile;
|
|
83
84
|
}
|
|
84
85
|
const structuralQuality = normalizeStructuralQualityConfig(input.structuralQuality);
|
|
86
|
+
const decisionEngine = normalizeDecisionPolicy(input.decisionEngine);
|
|
85
87
|
return {
|
|
86
88
|
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
87
89
|
protocolVersion: PROTOCOL_VERSION,
|
|
@@ -93,6 +95,7 @@ export function createConfig(input = {}) {
|
|
|
93
95
|
...(attestation ? { attestation } : {}),
|
|
94
96
|
...(executionProfile ? { executionProfile } : {}),
|
|
95
97
|
...(structuralQuality !== undefined ? { structuralQuality } : {}),
|
|
98
|
+
decisionEngine,
|
|
96
99
|
};
|
|
97
100
|
}
|
|
98
101
|
|
package/src/core/conformance.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isLedgerEventCollection } from "./ledger-event-collection.js";
|
|
1
2
|
import { PROTOCOL_VERSION } from "./protocol.js";
|
|
2
3
|
import { createEvidence } from "./evidence.js";
|
|
3
4
|
import { canonicalFingerprint } from "./artifacts.js";
|
|
@@ -36,7 +37,7 @@ export function delegationIsInScope({
|
|
|
36
37
|
if (state?.delegatedTasks && state.delegatedTasks.length > 0) return true;
|
|
37
38
|
if (state?.delegatedTaskIds && state.delegatedTaskIds.length > 0) return true;
|
|
38
39
|
if (receipt?.delegatedTasks && receipt.delegatedTasks.length > 0) return true;
|
|
39
|
-
if (
|
|
40
|
+
if (isLedgerEventCollection(events) && events.some((event) => typeof event?.type === "string" && event.type.toLowerCase().includes("delegat"))) {
|
|
40
41
|
return true;
|
|
41
42
|
}
|
|
42
43
|
return false;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const CONTEXT_BUDGETS = Object.freeze({
|
|
2
|
+
light: Object.freeze({ maxItems: 12, maxChars: 24_000 }),
|
|
3
|
+
balanced: Object.freeze({ maxItems: 32, maxChars: 64_000 }),
|
|
4
|
+
full: Object.freeze({ maxItems: 96, maxChars: 160_000 }),
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
export function contextBudget(profile = "balanced") {
|
|
8
|
+
return CONTEXT_BUDGETS[profile] ?? CONTEXT_BUDGETS.balanced;
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { canonicalFingerprint } from "../artifacts.js";
|
|
2
|
+
import { buildDecisionState } from "../decision/state-builder.js";
|
|
3
|
+
|
|
4
|
+
const INJECTION_PATTERN = /(ignore|disregard|override)\s+(?:all|previous|forge|system|developer)|exfiltrat|reveal\s+(?:the|all)\s+(?:secret|token|key)|execute\s+(?:this|the)\s+command/i;
|
|
5
|
+
|
|
6
|
+
export function normalizeContextCandidate(input = {}) {
|
|
7
|
+
const safe = buildDecisionState({
|
|
8
|
+
id: input.id ?? null,
|
|
9
|
+
sourceRef: input.sourceRef ?? null,
|
|
10
|
+
kind: input.kind ?? "UNKNOWN",
|
|
11
|
+
summary: input.summary ?? "",
|
|
12
|
+
required: input.required === true,
|
|
13
|
+
mandatory: input.mandatory === true,
|
|
14
|
+
risk: input.risk ?? "NORMAL",
|
|
15
|
+
trust: input.trust ?? "UNTRUSTED",
|
|
16
|
+
});
|
|
17
|
+
const summary = typeof safe.summary === "string" ? safe.summary : "";
|
|
18
|
+
const id = typeof safe.id === "string" && safe.id ? safe.id : `candidate-${canonicalFingerprint(safe).slice(0, 16)}`;
|
|
19
|
+
return {
|
|
20
|
+
...safe,
|
|
21
|
+
id,
|
|
22
|
+
summary,
|
|
23
|
+
chars: summary.length,
|
|
24
|
+
promptInjection: INJECTION_PATTERN.test(summary),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function normalizeContextCandidates(candidates = []) {
|
|
29
|
+
const seen = new Set();
|
|
30
|
+
const normalized = [];
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
const value = normalizeContextCandidate(candidate);
|
|
33
|
+
const identity = `${value.id}:${value.sourceRef ?? ""}`;
|
|
34
|
+
if (seen.has(identity)) continue;
|
|
35
|
+
seen.add(identity);
|
|
36
|
+
normalized.push(value);
|
|
37
|
+
}
|
|
38
|
+
return normalized;
|
|
39
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { contextBudget } from "./budget.js";
|
|
2
|
+
import { normalizeContextCandidates } from "./candidates.js";
|
|
3
|
+
import { contextPlanFingerprint } from "./fingerprint.js";
|
|
4
|
+
import { canonicalFingerprint } from "../artifacts.js";
|
|
5
|
+
import { assertContextCompilerPolicy, candidatePriority } from "./policy.js";
|
|
6
|
+
import { contextPlanResult } from "./result.js";
|
|
7
|
+
|
|
8
|
+
function orderCandidates(candidates, rankedIds = []) {
|
|
9
|
+
const ranks = new Map(rankedIds.map((id, index) => [id, rankedIds.length - index]));
|
|
10
|
+
return [...candidates].sort((a, b) => (b.mandatory - a.mandatory)
|
|
11
|
+
|| (b.required - a.required)
|
|
12
|
+
|| ((ranks.get(b.id) ?? 0) - (ranks.get(a.id) ?? 0))
|
|
13
|
+
|| (candidatePriority(b) - candidatePriority(a))
|
|
14
|
+
|| a.id.localeCompare(b.id));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function compileContext({ candidates = [], profile = "balanced", mandatoryIds = [], semanticRanker = null } = {}) {
|
|
18
|
+
const policy = assertContextCompilerPolicy({ profile, mandatoryIds });
|
|
19
|
+
const normalized = normalizeContextCandidates(candidates);
|
|
20
|
+
const candidateSetFingerprint = canonicalFingerprint(normalized.map((candidate) => ({
|
|
21
|
+
id: candidate.id,
|
|
22
|
+
sourceRef: candidate.sourceRef,
|
|
23
|
+
summary: candidate.summary,
|
|
24
|
+
required: candidate.required,
|
|
25
|
+
mandatory: candidate.mandatory,
|
|
26
|
+
})));
|
|
27
|
+
const mandatory = new Set(policy.mandatoryIds);
|
|
28
|
+
const marked = normalized.map((candidate) => ({ ...candidate, mandatory: candidate.mandatory || mandatory.has(candidate.id) }));
|
|
29
|
+
const semantic = typeof semanticRanker === "function" ? semanticRanker(marked.filter((item) => !item.promptInjection).map((item) => ({ id: item.id, summary: item.summary }))) : [];
|
|
30
|
+
const rankedIds = Array.isArray(semantic) ? semantic : (semantic?.rankedIds ?? []);
|
|
31
|
+
const excludedIds = new Set(Array.isArray(semantic) ? [] : (semantic?.excludedIds ?? []));
|
|
32
|
+
const ordered = orderCandidates(marked, Array.isArray(rankedIds) ? rankedIds : []);
|
|
33
|
+
const budget = contextBudget(profile);
|
|
34
|
+
const selected = [];
|
|
35
|
+
const omitted = [];
|
|
36
|
+
let chars = 0;
|
|
37
|
+
for (const candidate of ordered) {
|
|
38
|
+
const mustKeep = candidate.mandatory || candidate.required;
|
|
39
|
+
if (excludedIds.has(candidate.id) && !mustKeep) {
|
|
40
|
+
omitted.push(candidate);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const fits = selected.length < budget.maxItems && chars + candidate.chars <= budget.maxChars;
|
|
44
|
+
if (fits || mustKeep) {
|
|
45
|
+
selected.push(candidate);
|
|
46
|
+
chars += candidate.chars;
|
|
47
|
+
} else omitted.push(candidate);
|
|
48
|
+
}
|
|
49
|
+
const promptInjectionIds = marked.filter((item) => item.promptInjection).map((item) => item.id).sort();
|
|
50
|
+
const result = contextPlanResult({
|
|
51
|
+
profile,
|
|
52
|
+
candidates: marked,
|
|
53
|
+
selected,
|
|
54
|
+
omitted,
|
|
55
|
+
mandatoryIds: [...new Set([...policy.mandatoryIds, ...marked.filter((item) => item.mandatory).map((item) => item.id)])].sort(),
|
|
56
|
+
promptInjectionIds,
|
|
57
|
+
fingerprint: null,
|
|
58
|
+
budget,
|
|
59
|
+
candidateSetFingerprint,
|
|
60
|
+
});
|
|
61
|
+
result.decisionFingerprint = contextPlanFingerprint(result);
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { canonicalFingerprint } from "../artifacts.js";
|
|
2
|
+
|
|
3
|
+
export function contextPlanFingerprint(plan) {
|
|
4
|
+
return canonicalFingerprint({
|
|
5
|
+
profile: plan.profile,
|
|
6
|
+
selectedIds: plan.selected.map((item) => item.id),
|
|
7
|
+
omittedIds: plan.omitted.map((item) => item.id),
|
|
8
|
+
mandatoryIds: plan.mandatoryIds,
|
|
9
|
+
promptInjectionIds: plan.promptInjectionIds,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { decisionError, DECISION_ERROR_CODES } from "../decision/errors.js";
|
|
2
|
+
|
|
3
|
+
const RISK_ORDER = Object.freeze({ CRITICAL: 4, HIGH: 3, NORMAL: 2, LOW: 1 });
|
|
4
|
+
|
|
5
|
+
export function assertContextCompilerPolicy({ profile = "balanced", mandatoryIds = [] } = {}) {
|
|
6
|
+
if (!["light", "balanced", "full"].includes(profile)) throw decisionError(DECISION_ERROR_CODES.POLICY_INVALID, "Context compiler profile is invalid.");
|
|
7
|
+
if (!Array.isArray(mandatoryIds) || mandatoryIds.some((id) => typeof id !== "string" || !id)) throw decisionError(DECISION_ERROR_CODES.POLICY_INVALID, "Context compiler mandatory IDs are invalid.");
|
|
8
|
+
return { profile, mandatoryIds: [...new Set(mandatoryIds)] };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function candidatePriority(candidate) {
|
|
12
|
+
return (candidate.mandatory || candidate.required ? 100 : 0) + (candidate.promptInjection ? -50 : 0) + (RISK_ORDER[candidate.risk] ?? 0);
|
|
13
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function contextPlanResult({ profile, candidates, selected, omitted, mandatoryIds, promptInjectionIds, fingerprint, budget, candidateSetFingerprint }) {
|
|
2
|
+
return {
|
|
3
|
+
schemaVersion: 1,
|
|
4
|
+
protocolVersion: 1,
|
|
5
|
+
profile,
|
|
6
|
+
budget,
|
|
7
|
+
candidateItems: candidates.length,
|
|
8
|
+
selectedItems: selected.length,
|
|
9
|
+
candidateChars: candidates.reduce((total, item) => total + item.chars, 0),
|
|
10
|
+
selectedChars: selected.reduce((total, item) => total + item.chars, 0),
|
|
11
|
+
selected,
|
|
12
|
+
omitted,
|
|
13
|
+
mandatoryIds,
|
|
14
|
+
promptInjectionIds,
|
|
15
|
+
candidateSetFingerprint,
|
|
16
|
+
tokenUsage: { inputTokens: null, outputTokens: null, reportedBy: "UNKNOWN" },
|
|
17
|
+
decisionFingerprint: fingerprint,
|
|
18
|
+
authority: "SEMANTIC_DECISION",
|
|
19
|
+
evidenceAuthority: "NONE",
|
|
20
|
+
lifecycleAuthority: false,
|
|
21
|
+
completionAuthority: false,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { assertSafePath, ensureWithin, fileExists } from "./filesystem.js";
|
|
2
|
+
import { operationalArtifactExists } from "../storage/operational-context.js";
|
|
3
|
+
import { withProjectReadSnapshot } from "../storage/project-read-snapshot.js";
|
|
2
4
|
|
|
3
5
|
function finding(code, severity, field, itemId = null) {
|
|
4
6
|
return { code, severity, field, itemId };
|
|
@@ -15,7 +17,16 @@ function hasOperationalHints(continuity) {
|
|
|
15
17
|
);
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
async function inspectPathExists(target, relativePath) {
|
|
21
|
+
return operationalArtifactExists(target, relativePath) ?? await fileExists(ensureWithin(target, relativePath));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function lintContinuity(options = {}) {
|
|
25
|
+
if (typeof options.target !== "string" || options.target.trim() === "") return lintSelectedContinuity(options);
|
|
26
|
+
return withProjectReadSnapshot(options.target, () => lintSelectedContinuity(options));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function lintSelectedContinuity({ target, continuity, state } = {}) {
|
|
19
30
|
const findings = [];
|
|
20
31
|
if (!continuity || typeof continuity !== "object" || Array.isArray(continuity)) {
|
|
21
32
|
return { status: "PASS", findings };
|
|
@@ -64,7 +75,7 @@ export async function lintContinuity({ target, continuity, state } = {}) {
|
|
|
64
75
|
for (const [index, inspectPath] of (continuity.inspectFirst ?? []).entries()) {
|
|
65
76
|
try {
|
|
66
77
|
await assertSafePath(target, inspectPath);
|
|
67
|
-
if (!(await
|
|
78
|
+
if (!(await inspectPathExists(target, inspectPath))) {
|
|
68
79
|
findings.push(finding(
|
|
69
80
|
"CONTINUITY_INSPECT_PATH_MISSING",
|
|
70
81
|
"WARN",
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { getOperationalStore } from "../storage/operational-context.js";
|
|
2
|
+
import { withEventLedgerAudit } from "./events.js";
|
|
1
3
|
import { canonicalFingerprint } from "./artifacts.js";
|
|
2
4
|
import { assertContinuitySemantics, readContinuity } from "./continuity.js";
|
|
3
5
|
import { WORK_TRANSITIONS } from "./protocol.js";
|
|
4
6
|
import { lintContinuity } from "./continuity-lint.js";
|
|
7
|
+
import { withNativeReadScope } from "./native-storage.js";
|
|
5
8
|
|
|
6
9
|
const RECONCILIATION_CODE = "E_CONTINUITY_RECONCILIATION_REQUIRED";
|
|
7
10
|
|
|
@@ -171,6 +174,14 @@ export function classifyContinuity({
|
|
|
171
174
|
}
|
|
172
175
|
|
|
173
176
|
export async function reconcileContinuity({ target, packageRoot, taskId = null } = {}) {
|
|
177
|
+
const read = () => reconcileLoadedContinuity({ target, packageRoot, taskId });
|
|
178
|
+
return withNativeReadScope(target, () => {
|
|
179
|
+
if (getOperationalStore(target) && taskId) return withEventLedgerAudit(target, packageRoot, { taskId }, read);
|
|
180
|
+
return read();
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async function reconcileLoadedContinuity({ target, packageRoot, taskId }) {
|
|
174
185
|
const [{ readWorkState }, { readContract }, repository] = await Promise.all([
|
|
175
186
|
import("./work-state.js"),
|
|
176
187
|
import("./contract.js"),
|
|
@@ -267,12 +278,14 @@ async function resolveLatestHandoffSafe(target, { packageRoot, taskId } = {}) {
|
|
|
267
278
|
|
|
268
279
|
async function deriveDiagnosticContextSafe({ target, packageRoot, state }) {
|
|
269
280
|
try {
|
|
270
|
-
const [{
|
|
281
|
+
const [{ withEventLedgerAudit }, { deriveDiagnosticContext }] = await Promise.all([
|
|
271
282
|
import("./events.js"),
|
|
272
283
|
import("./reflection.js"),
|
|
273
284
|
]);
|
|
274
|
-
|
|
275
|
-
|
|
285
|
+
return await withEventLedgerAudit(target, packageRoot, { taskId: state?.taskId ?? null }, audit => {
|
|
286
|
+
if (!audit.valid) return { present: false };
|
|
287
|
+
return { present: true, ...deriveDiagnosticContext(audit.events, state) };
|
|
288
|
+
});
|
|
276
289
|
} catch {
|
|
277
290
|
return { present: false };
|
|
278
291
|
}
|
package/src/core/continuity.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { withExistingProjectScope } from "../storage/existing-project-scope.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -7,11 +7,12 @@ import {
|
|
|
7
7
|
readJsonArtifact,
|
|
8
8
|
writeJsonArtifact,
|
|
9
9
|
} from "./artifacts.js";
|
|
10
|
-
import { assertSafePath, ensureWithin, fileExists } from "./filesystem.js";
|
|
11
10
|
import { PROTOCOL_VERSION, WORK_PHASES } from "./protocol.js";
|
|
12
11
|
import { normalizePortableText, assertPortableContextSafe } from "./portable-context.js";
|
|
13
12
|
import { getPackageRoot } from "./templates.js";
|
|
14
13
|
import { taskArtifactPath } from "./task-paths.js";
|
|
14
|
+
import { getOperationalStore, readOperationalText } from "../storage/operational-context.js";
|
|
15
|
+
import { withTaskTransaction } from "./transaction.js";
|
|
15
16
|
|
|
16
17
|
export const CONTINUITY_PATH = ARTIFACT_PATHS.continuity;
|
|
17
18
|
export const CONTINUITY_SCHEMA_VERSION = 1;
|
|
@@ -242,10 +243,17 @@ export async function writeContinuity(target, operationalInput = {}, options = {
|
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
export async function clearContinuity(target, options = {}) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
-
if (
|
|
249
|
-
|
|
250
|
-
|
|
246
|
+
if (!options.taskId) throw Object.assign(new Error("Canonical artifact clearing requires a task identity"), { code: "E_STORAGE_OPERATION_UNSUPPORTED" });
|
|
247
|
+
const relPath = taskArtifactPath(options.taskId, "continuity");
|
|
248
|
+
const requested = options.continuityPath ?? options.relativePath ?? relPath;
|
|
249
|
+
if (requested !== relPath) throw Object.assign(new Error("Artifact clearing requires the canonical task path; portable exports are independent files"), { code: "E_STORAGE_OPERATION_UNSUPPORTED", artifacts: [requested] });
|
|
250
|
+
if (!getOperationalStore(target)) {
|
|
251
|
+
return withExistingProjectScope(target, () => clearContinuity(target, options));
|
|
252
|
+
}
|
|
253
|
+
const operational = readOperationalText(target, relPath);
|
|
254
|
+
if (operational.text === null) return { removed: false, path: relPath };
|
|
255
|
+
return withTaskTransaction({ target, taskId: options.taskId, operation: "clear-continuity", packageRoot: options.packageRoot }, async transaction => {
|
|
256
|
+
transaction.stageDelete(relPath);
|
|
257
|
+
return { removed: true, path: relPath };
|
|
258
|
+
});
|
|
251
259
|
}
|