@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/work-state.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { withProjectReadSnapshot } from "../storage/project-read-snapshot.js";
|
|
2
|
+
import { withExistingProjectScope } from "../storage/existing-project-scope.js";
|
|
1
3
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { unlink } from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
|
|
5
6
|
import {
|
|
@@ -7,7 +8,6 @@ import {
|
|
|
7
8
|
ensureWithin,
|
|
8
9
|
fileExists,
|
|
9
10
|
readBytes,
|
|
10
|
-
writeFileAtomic,
|
|
11
11
|
} from "./filesystem.js";
|
|
12
12
|
import { GUIDE_IDS, PROTOCOL_VERSION, assertFailureClass, assertWorkPhase, isValidTransition } from "./protocol.js";
|
|
13
13
|
import { assertSchema, readSchema } from "./schema-validation.js";
|
|
@@ -20,6 +20,8 @@ import { assertCoverageList } from "./coverage.js";
|
|
|
20
20
|
import { canonicalFingerprint } from "./artifacts.js";
|
|
21
21
|
import { taskArtifactPath } from "./task-paths.js";
|
|
22
22
|
import { getTaskTransaction, withTaskTransaction } from "./transaction.js";
|
|
23
|
+
import { readOperationalText, getOperationalStore } from "../storage/operational-context.js";
|
|
24
|
+
import { withNativeReadScope } from "./native-storage.js";
|
|
23
25
|
|
|
24
26
|
export const WORK_STATE_PATH = ".forgeloop/work-state.json";
|
|
25
27
|
|
|
@@ -236,67 +238,83 @@ async function validateStoredState(state, packageRoot = getPackageRoot()) {
|
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
export async function readWorkState(target, options = {}) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (staged === null) {
|
|
251
|
-
if (!(await fileExists(statePath))) return null;
|
|
252
|
-
const bytes = await readBytes(statePath);
|
|
253
|
-
assertJsonBytes(bytes, relPath);
|
|
254
|
-
state = JSON.parse(bytes.toString("utf8"));
|
|
255
|
-
} else {
|
|
256
|
-
const bytes = Buffer.from(staged, "utf8");
|
|
257
|
-
assertJsonBytes(bytes, relPath);
|
|
258
|
-
state = JSON.parse(staged);
|
|
241
|
+
return withNativeReadScope(target, async () => {
|
|
242
|
+
const packageRoot = typeof options === "string" ? options : (options?.packageRoot ?? getPackageRoot());
|
|
243
|
+
const relPath = typeof options === "object" && options !== null
|
|
244
|
+
? (options.statePath ?? options.relativePath ?? (options.taskId ? taskArtifactPath(options.taskId, "state") : (options.taskContext ? options.taskContext.paths.state : WORK_STATE_PATH)))
|
|
245
|
+
: WORK_STATE_PATH;
|
|
246
|
+
|
|
247
|
+
const operational = readOperationalText(target, relPath);
|
|
248
|
+
if (operational.selected) {
|
|
249
|
+
if (operational.text === null) return null;
|
|
250
|
+
assertJsonBytes(operational.text, relPath);
|
|
251
|
+
return validateStoredState(JSON.parse(operational.text), packageRoot);
|
|
259
252
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
253
|
+
await assertSafePath(target, relPath);
|
|
254
|
+
const statePath = ensureWithin(target, relPath);
|
|
255
|
+
let state;
|
|
256
|
+
try {
|
|
257
|
+
const transaction = (await getTaskTransaction(target));
|
|
258
|
+
const staged = transaction ? await transaction.readText(relPath) : null;
|
|
259
|
+
if (staged === null) {
|
|
260
|
+
if (!(await fileExists(statePath))) return null;
|
|
261
|
+
const bytes = await readBytes(statePath);
|
|
262
|
+
assertJsonBytes(bytes, relPath);
|
|
263
|
+
state = JSON.parse(bytes.toString("utf8"));
|
|
264
|
+
} else {
|
|
265
|
+
const bytes = Buffer.from(staged, "utf8");
|
|
266
|
+
assertJsonBytes(bytes, relPath);
|
|
267
|
+
state = JSON.parse(staged);
|
|
268
|
+
}
|
|
269
|
+
} catch (error) {
|
|
270
|
+
throw new WorkStateError(`Unable to parse ${relPath}: ${error.message}`);
|
|
271
|
+
}
|
|
272
|
+
try {
|
|
273
|
+
return await validateStoredState(state, packageRoot);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
if (error instanceof WorkStateError) throw error;
|
|
276
|
+
throw new WorkStateError(error.message);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
269
279
|
}
|
|
270
280
|
|
|
271
281
|
export async function readContractFingerprint(target, contractFile) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
282
|
+
return withNativeReadScope(target, async () => {
|
|
283
|
+
const operational = readOperationalText(target, contractFile);
|
|
284
|
+
if (operational.selected) {
|
|
285
|
+
if (operational.text === null) throw new WorkStateError(`Unable to parse contract ${contractFile}: artifact missing`);
|
|
286
|
+
assertJsonBytes(operational.text, contractFile);
|
|
287
|
+
return { path: contractFile, fingerprint: contractFingerprint(JSON.parse(operational.text)) };
|
|
288
|
+
}
|
|
289
|
+
await assertSafePath(target, contractFile);
|
|
290
|
+
const contractPath = ensureWithin(target, contractFile);
|
|
291
|
+
let contract;
|
|
292
|
+
try {
|
|
293
|
+
const bytes = await readBytes(contractPath);
|
|
294
|
+
assertJsonBytes(bytes, contractFile);
|
|
295
|
+
contract = JSON.parse(bytes.toString("utf8"));
|
|
296
|
+
} catch (error) {
|
|
297
|
+
throw new WorkStateError(`Unable to parse contract ${contractFile}: ${error.message}`);
|
|
298
|
+
}
|
|
299
|
+
return { path: contractFile, fingerprint: contractFingerprint(contract) };
|
|
300
|
+
});
|
|
283
301
|
}
|
|
284
302
|
|
|
285
303
|
export async function writeWorkState(target, state, options = {}) {
|
|
286
304
|
const packageRoot = options?.packageRoot ?? getPackageRoot();
|
|
287
305
|
const dryRun = options?.dryRun ?? false;
|
|
288
|
-
const relPath = options?.statePath ?? options?.relativePath ?? (options?.taskId ? taskArtifactPath(options.taskId, "state") : WORK_STATE_PATH);
|
|
289
|
-
|
|
290
306
|
await validateStoredState(state, packageRoot);
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
307
|
+
const canonicalPath = taskArtifactPath(state.taskId, "state");
|
|
308
|
+
const relativePath = options?.statePath ?? options?.relativePath ?? canonicalPath;
|
|
309
|
+
if ((options?.taskId && options.taskId !== state.taskId) || relativePath !== canonicalPath) {
|
|
310
|
+
throw Object.assign(new Error("Work-state writes require their canonical task-scoped SQLite identity; use explicit export for portable files"), { code: "E_STORAGE_OPERATION_UNSUPPORTED", artifacts: [relativePath] });
|
|
311
|
+
}
|
|
312
|
+
if (dryRun) return state;
|
|
313
|
+
if (!getOperationalStore(target)) {
|
|
314
|
+
const { withProjectStorage } = await import("../storage/project-boundary.js");
|
|
315
|
+
return withProjectStorage(target, () => writeWorkState(target, state, options));
|
|
299
316
|
}
|
|
317
|
+
await withTaskTransaction({ target, taskId: state.taskId, operation: "write-state", packageRoot }, tx => tx.stageText(canonicalPath, `${JSON.stringify(state, null, 2)}\n`));
|
|
300
318
|
return state;
|
|
301
319
|
}
|
|
302
320
|
|
|
@@ -355,18 +373,34 @@ export async function initializeWorkState(target, state, { packageRoot = getPack
|
|
|
355
373
|
}
|
|
356
374
|
|
|
357
375
|
export async function clearWorkState(target, options = {}) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
|
|
376
|
+
if (!options.taskId) throw Object.assign(new Error("Canonical artifact clearing requires a task identity"), { code: "E_STORAGE_OPERATION_UNSUPPORTED" });
|
|
377
|
+
const relPath = taskArtifactPath(options.taskId, "state");
|
|
378
|
+
const requested = options.statePath ?? options.relativePath ?? relPath;
|
|
379
|
+
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] });
|
|
380
|
+
if (!getOperationalStore(target)) {
|
|
381
|
+
return withExistingProjectScope(target, () => clearWorkState(target, options));
|
|
382
|
+
}
|
|
383
|
+
const operational = readOperationalText(target, relPath);
|
|
384
|
+
if (operational.text === null) return { removed: false, path: relPath };
|
|
385
|
+
return withTaskTransaction({ target, taskId: options.taskId, operation: "clear-work-state", packageRoot: options.packageRoot }, async transaction => {
|
|
386
|
+
transaction.stageDelete(relPath);
|
|
387
|
+
return { removed: true, path: relPath };
|
|
388
|
+
});
|
|
364
389
|
}
|
|
365
390
|
|
|
366
391
|
export async function readRequiredArtifactFingerprints(target, artifacts) {
|
|
392
|
+
return withProjectReadSnapshot(target, () => readSelectedRequiredArtifactFingerprints(target, artifacts));
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async function readSelectedRequiredArtifactFingerprints(target, artifacts) {
|
|
367
396
|
const normalized = normalizeRequiredArtifacts(artifacts);
|
|
368
397
|
const current = [];
|
|
369
398
|
for (const artifact of normalized) {
|
|
399
|
+
const operational = readOperationalText(target, artifact.path);
|
|
400
|
+
if (operational.selected) {
|
|
401
|
+
current.push({ path: artifact.path, sha256: operational.text === null ? null : createHash("sha256").update(operational.text).digest("hex"), status: operational.text === null ? "missing" : "present" });
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
370
404
|
await assertSafePath(target, artifact.path);
|
|
371
405
|
const artifactPath = ensureWithin(target, artifact.path);
|
|
372
406
|
if (!(await fileExists(artifactPath))) {
|
|
@@ -485,6 +519,7 @@ export async function classifyLoadedWorkState({ target, state, contractFile = nu
|
|
|
485
519
|
try {
|
|
486
520
|
contract = await readContractFingerprint(target, contractFile);
|
|
487
521
|
} catch (error) {
|
|
522
|
+
if (error?.code === "E_STATE_REVISION_CONFLICT") throw error;
|
|
488
523
|
contractError = error.message;
|
|
489
524
|
}
|
|
490
525
|
}
|
|
@@ -495,6 +530,7 @@ export async function classifyLoadedWorkState({ target, state, contractFile = nu
|
|
|
495
530
|
try {
|
|
496
531
|
currentArtifacts = await readRequiredArtifactFingerprints(target, state.requiredArtifacts);
|
|
497
532
|
} catch (error) {
|
|
533
|
+
if (error?.code === "E_STATE_REVISION_CONFLICT") throw error;
|
|
498
534
|
artifactError = error.message;
|
|
499
535
|
}
|
|
500
536
|
} else {
|
|
@@ -547,7 +583,11 @@ export async function classifyLoadedWorkState({ target, state, contractFile = nu
|
|
|
547
583
|
};
|
|
548
584
|
}
|
|
549
585
|
|
|
550
|
-
export async function readAndClassifyWorkState(
|
|
586
|
+
export async function readAndClassifyWorkState(options = {}) {
|
|
587
|
+
return withProjectReadSnapshot(options.target, () => readAndClassifySelectedWorkState(options));
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
async function readAndClassifySelectedWorkState({ target, packageRoot = getPackageRoot(), contractFile = null, maxAgeMs, taskId = null, stateFile = null, statePath = null } = {}) {
|
|
551
591
|
const effectiveStateRel = stateFile ?? statePath ?? (taskId ? taskArtifactPath(taskId, "state") : WORK_STATE_PATH);
|
|
552
592
|
let state = null;
|
|
553
593
|
try {
|
|
@@ -557,6 +597,7 @@ export async function readAndClassifyWorkState({ target, packageRoot = getPackag
|
|
|
557
597
|
...(stateFile || statePath ? { statePath: effectiveStateRel } : {}),
|
|
558
598
|
});
|
|
559
599
|
} catch (error) {
|
|
600
|
+
if (error?.code === "E_STATE_REVISION_CONFLICT") throw error;
|
|
560
601
|
return {
|
|
561
602
|
path: effectiveStateRel,
|
|
562
603
|
present: true,
|