@ornexus/neocortex 4.60.73 → 4.60.75
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/dist/release-source.json +1 -1
- package/dist/sbom.cdx.json +1216 -1210
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +2 -2
- package/packages/client/dist/adapters/adapter-registry.js +1 -108
- package/packages/client/dist/adapters/antigravity-adapter.js +2 -77
- package/packages/client/dist/adapters/claude-code-adapter.js +3 -79
- package/packages/client/dist/adapters/codex-adapter.js +2 -80
- package/packages/client/dist/adapters/cursor-adapter.js +4 -115
- package/packages/client/dist/adapters/gemini-adapter.js +2 -71
- package/packages/client/dist/adapters/grok-adapter.js +2 -42
- package/packages/client/dist/adapters/index.js +1 -22
- package/packages/client/dist/adapters/platform-detector.js +1 -212
- package/packages/client/dist/adapters/target-adapter.js +0 -12
- package/packages/client/dist/adapters/vscode-adapter.js +2 -72
- package/packages/client/dist/agent/refresh-stubs.js +2 -417
- package/packages/client/dist/agent/update-agent-yaml.js +1 -102
- package/packages/client/dist/agent/update-description.js +1 -251
- package/packages/client/dist/cache/crypto-utils.js +1 -78
- package/packages/client/dist/cache/encrypted-cache.d.ts +27 -0
- package/packages/client/dist/cache/encrypted-cache.js +1 -108
- package/packages/client/dist/cache/in-memory-asset-cache.js +1 -73
- package/packages/client/dist/cache/index.js +1 -13
- package/packages/client/dist/cache/protected-pi-boundary.js +1 -44
- package/packages/client/dist/checkpoint/checkpoint-client-reader.js +2 -127
- package/packages/client/dist/checkpoint/index.js +1 -11
- package/packages/client/dist/checkpoint/shared-checkpoint-types.js +1 -32
- package/packages/client/dist/cli.js +5 -358
- package/packages/client/dist/commands/activate.js +8 -394
- package/packages/client/dist/commands/architecture-answers.js +7 -274
- package/packages/client/dist/commands/architecture-memory-terminal.js +4 -253
- package/packages/client/dist/commands/architecture-non-ui-continuation.js +1 -100
- package/packages/client/dist/commands/architecture-root-binding.js +1 -51
- package/packages/client/dist/commands/cache-status.js +2 -112
- package/packages/client/dist/commands/config.js +1 -88
- package/packages/client/dist/commands/doctor.js +2 -635
- package/packages/client/dist/commands/invoke.d.ts +38 -1
- package/packages/client/dist/commands/invoke.js +143 -7200
- package/packages/client/dist/commands/legacy-epic-terminal.js +1 -71
- package/packages/client/dist/commands/legacy-story-branch.js +1 -96
- package/packages/client/dist/commands/legacy-story-pr.js +1 -276
- package/packages/client/dist/commands/mutation-qa-checkpoint.js +5 -285
- package/packages/client/dist/commands/mutation-qa-gate.js +1 -54
- package/packages/client/dist/commands/mutation-qa-git.js +1 -41
- package/packages/client/dist/commands/mutation-qa-policy.js +1 -102
- package/packages/client/dist/commands/mutation-qa-run.js +3 -219
- package/packages/client/dist/commands/mutation-qa-verdict.js +1 -149
- package/packages/client/dist/commands/mutation-qa.js +1 -220
- package/packages/client/dist/commands/native-agent.js +2 -136
- package/packages/client/dist/commands/planning-diagnosis.js +1 -43
- package/packages/client/dist/commands/planning-generation.js +1 -53
- package/packages/client/dist/commands/planning-memory.js +1 -40
- package/packages/client/dist/commands/planning-research.js +1 -42
- package/packages/client/dist/commands/private-session.js +1 -75
- package/packages/client/dist/commands/property-qa.js +1 -139
- package/packages/client/dist/commands/qa-control.js +1 -16
- package/packages/client/dist/commands/qa-scan-browser-launch.js +1 -55
- package/packages/client/dist/commands/qa-scan-browser-route.js +1 -28
- package/packages/client/dist/commands/qa-scan-capture.js +5 -663
- package/packages/client/dist/commands/qa-scan-discovery.js +3 -376
- package/packages/client/dist/commands/qa-scan-review.js +5 -826
- package/packages/client/dist/commands/qa-synthetic-backend-capture.js +1 -266
- package/packages/client/dist/commands/qa-synthetic-backend-review.js +1 -297
- package/packages/client/dist/commands/qa-synthetic-backend.js +2 -340
- package/packages/client/dist/commands/qa-synthetic-broker-port.js +1 -85
- package/packages/client/dist/commands/qa-synthetic-browser.js +1 -39
- package/packages/client/dist/commands/refactor-characterization.js +21 -671
- package/packages/client/dist/commands/refactor-commit.js +13 -399
- package/packages/client/dist/commands/refactor-control.js +3 -142
- package/packages/client/dist/commands/refactor-cpp-assertions.js +3 -93
- package/packages/client/dist/commands/refactor-review.js +5 -283
- package/packages/client/dist/commands/refactor-root.js +7 -588
- package/packages/client/dist/commands/refresh-memory.js +3 -156
- package/packages/client/dist/commands/shared-architecture-non-ui.js +1 -24
- package/packages/client/dist/commands/story-checkpoint.js +1 -171
- package/packages/client/dist/config/host-auth-broker.d.ts +31 -0
- package/packages/client/dist/config/host-auth-broker.js +1 -0
- package/packages/client/dist/config/host-auth-reference.d.ts +32 -0
- package/packages/client/dist/config/host-auth-reference.js +1 -0
- package/packages/client/dist/config/profile-directory.js +1 -13
- package/packages/client/dist/config/resolver-selection.js +1 -278
- package/packages/client/dist/config/secure-config.js +12 -281
- package/packages/client/dist/config.js +2 -223
- package/packages/client/dist/constants.js +1 -25
- package/packages/client/dist/context/context-collector.js +2 -222
- package/packages/client/dist/context/context-sanitizer.js +1 -145
- package/packages/client/dist/continuity/autonomous-governance.js +1 -285
- package/packages/client/dist/continuity/continuity-client-state-store.js +1 -1587
- package/packages/client/dist/continuity/invoke-hooks.js +1 -129
- package/packages/client/dist/continuity/migrations/001-initial-schema.js +2 -12
- package/packages/client/dist/continuity/migrations/002-processing-output-summary-indexes.js +2 -12
- package/packages/client/dist/continuity/migrations/003-headless-execution-attempts.js +2 -12
- package/packages/client/dist/continuity/migrations/004-outbox-delivery-state.js +2 -12
- package/packages/client/dist/continuity/migrations/005-bounded-headless-queue.js +2 -12
- package/packages/client/dist/continuity/migrations/006-native-agent-dispatches.js +2 -10
- package/packages/client/dist/continuity/native-agent-store.js +1 -69
- package/packages/client/dist/continuity/native-agent-types.d.ts +11 -0
- package/packages/client/dist/continuity/native-agent-types.js +1 -90
- package/packages/client/dist/continuity/outbox.js +1 -117
- package/packages/client/dist/continuity/runner-bootstrap-policy.js +1 -172
- package/packages/client/dist/continuity/sqlite-store.js +81 -2612
- package/packages/client/dist/effects/invoke-effect-gateways.js +1 -62
- package/packages/client/dist/errors/error-messages.d.ts +3 -0
- package/packages/client/dist/errors/error-messages.js +2 -228
- package/packages/client/dist/errors/frontmatter-diagnostics.js +1 -125
- package/packages/client/dist/evidence/collector.js +1 -347
- package/packages/client/dist/evidence/index.js +1 -1
- package/packages/client/dist/evidence/types.js +0 -2
- package/packages/client/dist/fs/atomic-state-replace.js +1 -152
- package/packages/client/dist/generated/command-registry.generated.js +1 -4076
- package/packages/client/dist/generated/public-projections.generated.js +1 -149
- package/packages/client/dist/git/direct-yolo-c01-retry.js +4 -138
- package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +11 -1
- package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -1234
- package/packages/client/dist/git/epic-operational-state.js +2 -672
- package/packages/client/dist/git/git-lifecycle-step-ids.js +1 -14
- package/packages/client/dist/git/git-lifecycle-store.d.ts +23 -0
- package/packages/client/dist/git/git-lifecycle-store.js +10 -1981
- package/packages/client/dist/git/legacy-story-branch-checkpoint.js +9 -259
- package/packages/client/dist/git/legacy-story-branch-setup.js +4 -348
- package/packages/client/dist/git/legacy-story-pr.js +70 -3538
- package/packages/client/dist/git/secure-filesystem-boundary.js +5 -182
- package/packages/client/dist/graph-retrieval/pre-command-hook.js +1 -284
- package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -237
- package/packages/client/dist/i18n/first-run.js +2 -60
- package/packages/client/dist/index.d.ts +2 -0
- package/packages/client/dist/index.js +1 -47
- package/packages/client/dist/invocation/invoke-input.js +1 -24
- package/packages/client/dist/license/host-auth-recovery.d.ts +158 -0
- package/packages/client/dist/license/host-auth-recovery.js +1 -0
- package/packages/client/dist/license/index.js +1 -5
- package/packages/client/dist/license/license-client.d.ts +10 -1
- package/packages/client/dist/license/license-client.js +1 -304
- package/packages/client/dist/machine/fingerprint.js +2 -163
- package/packages/client/dist/machine/index.js +1 -5
- package/packages/client/dist/memory/project-memory-path-scope.js +1 -62
- package/packages/client/dist/memory/project-memory-writer.js +40 -1007
- package/packages/client/dist/memory/shared-project-memory-types.js +2 -253
- package/packages/client/dist/migrations/epic-lifecycle-backfill.js +3 -1060
- package/packages/client/dist/migrations/project-identity-capability.js +1 -50
- package/packages/client/dist/migrations/project-identity.js +7 -493
- package/packages/client/dist/migrations/state-json.js +4 -393
- package/packages/client/dist/policy/architecture-policy.js +2 -184
- package/packages/client/dist/policy/index.js +1 -7
- package/packages/client/dist/policy/shared-policy-types.js +0 -38
- package/packages/client/dist/policy/subagent-approval-policy.js +1 -55
- package/packages/client/dist/private-execution/clean-baseline.js +2 -279
- package/packages/client/dist/private-execution/codex-executor.js +4 -574
- package/packages/client/dist/private-execution/codex-host-runtime.js +1 -137
- package/packages/client/dist/private-execution/codex-lifecycle-guard.js +1 -97
- package/packages/client/dist/private-execution/codex-scoped-permissions.js +1 -128
- package/packages/client/dist/private-execution/delivery.js +13 -410
- package/packages/client/dist/private-execution/diagnosis-root-review.js +2 -294
- package/packages/client/dist/private-execution/frozen-handoff.js +6 -19
- package/packages/client/dist/private-execution/implementation-validation.js +2 -106
- package/packages/client/dist/private-execution/isolated-admission.js +23 -1432
- package/packages/client/dist/private-execution/isolated-session.js +5 -725
- package/packages/client/dist/private-execution/isolated-workspace.js +1 -122
- package/packages/client/dist/private-execution/pact-consumer-runtime.js +3 -409
- package/packages/client/dist/private-execution/pact-test-source.js +1 -258
- package/packages/client/dist/private-execution/pact-toolchain.js +3 -290
- package/packages/client/dist/private-execution/pact-write-set.js +1 -172
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -406
- package/packages/client/dist/private-execution/planning-generation-checkpoint.js +5 -462
- package/packages/client/dist/private-execution/planning-memory-checkpoint.js +3 -139
- package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -325
- package/packages/client/dist/private-execution/private-report-store.js +1 -42
- package/packages/client/dist/private-execution/property-test-candidate.js +1 -103
- package/packages/client/dist/private-execution/property-test-choices.js +3 -147
- package/packages/client/dist/private-execution/property-test-plan.js +7 -271
- package/packages/client/dist/private-execution/property-test-review.js +4 -258
- package/packages/client/dist/private-execution/property-test-runtime.js +9 -372
- package/packages/client/dist/private-execution/property-test-source.js +1 -139
- package/packages/client/dist/private-execution/root-checkpoint.js +1 -80
- package/packages/client/dist/private-execution/root-memory-git-evidence.js +3 -135
- package/packages/client/dist/private-execution/root-memory-recovery.js +1 -93
- package/packages/client/dist/private-execution/root-memory-request.js +1 -29
- package/packages/client/dist/private-execution/root-memory-scope.js +1 -178
- package/packages/client/dist/private-execution/root-memory-writer.js +1 -102
- package/packages/client/dist/private-execution/session-lease.js +1 -63
- package/packages/client/dist/private-execution/shared-private-admission-types.js +1 -50
- package/packages/client/dist/private-execution/shared-project-validation.js +1 -66
- package/packages/client/dist/private-execution/shared-root-memory-types.js +1 -61
- package/packages/client/dist/private-execution/ux-source-validation.js +1 -372
- package/packages/client/dist/private-execution/ux-write-set.js +2 -191
- package/packages/client/dist/registry/registry-reconciliation.js +1 -234
- package/packages/client/dist/resilience/circuit-breaker.js +1 -170
- package/packages/client/dist/resilience/degradation-manager.js +1 -164
- package/packages/client/dist/resilience/freshness-indicator.js +1 -100
- package/packages/client/dist/resilience/index.js +1 -8
- package/packages/client/dist/resilience/recovery-detector.js +1 -74
- package/packages/client/dist/resolvers/asset-resolver.js +0 -13
- package/packages/client/dist/resolvers/local-resolver.js +8 -255
- package/packages/client/dist/resolvers/remote-resolver.js +1 -233
- package/packages/client/dist/runner/binary.js +1 -404
- package/packages/client/dist/runner/cli.js +17 -1571
- package/packages/client/dist/runner/epic-background-dispatcher.d.ts +61 -0
- package/packages/client/dist/runner/epic-background-dispatcher.js +1 -0
- package/packages/client/dist/runner/headless/adapters.js +1 -49
- package/packages/client/dist/runner/headless/background-root.d.ts +65 -0
- package/packages/client/dist/runner/headless/background-root.js +1 -0
- package/packages/client/dist/runner/headless/claude-code-adapter.js +1 -79
- package/packages/client/dist/runner/headless/continuous-story-workspace.js +11 -1628
- package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -69
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +1 -1
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +2 -110
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +2 -0
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +10 -1236
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +27 -2
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -318
- package/packages/client/dist/runner/headless/fake-adapter.js +1 -62
- package/packages/client/dist/runner/headless/managed-environment-cleanup.d.ts +95 -0
- package/packages/client/dist/runner/headless/managed-environment-cleanup.js +1 -0
- package/packages/client/dist/runner/headless/managed-profile.js +1 -132
- package/packages/client/dist/runner/headless/opencode-adapter.js +2 -145
- package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -43
- package/packages/client/dist/runner/headless/resolver.js +1 -231
- package/packages/client/dist/runner/headless/run-yolo.js +1 -885
- package/packages/client/dist/runner/headless/run-yoloop.d.ts +1 -0
- package/packages/client/dist/runner/headless/run-yoloop.js +2 -2574
- package/packages/client/dist/runner/headless/types.js +2 -574
- package/packages/client/dist/runner/local-console.js +13 -396
- package/packages/client/dist/runner/portal-sync-worker.js +1 -1487
- package/packages/client/dist/runner/project-identity.js +1 -106
- package/packages/client/dist/runner/scheduler.js +7 -995
- package/packages/client/dist/runner-cli.js +2 -18
- package/packages/client/dist/state/invocation-shape.js +1 -13
- package/packages/client/dist/state/project-state-snapshot.d.ts +7 -0
- package/packages/client/dist/state/project-state-snapshot.js +1 -1731
- package/packages/client/dist/state/state-json-repair.js +3 -785
- package/packages/client/dist/state/structural-dag-projection.js +1 -118
- package/packages/client/dist/telemetry/index.js +1 -5
- package/packages/client/dist/telemetry/offline-queue.js +1 -131
- package/packages/client/dist/tier/index.js +1 -5
- package/packages/client/dist/tier/tier-aware-client.js +1 -405
- package/packages/client/dist/types/index.js +1 -38
- package/packages/client/dist/version.js +1 -27
- package/packages/client/dist/yolo/change-evidence-collector.d.ts +21 -1
- package/packages/client/dist/yolo/change-evidence-collector.js +1 -126
- package/packages/client/dist/yolo/invoke-envelope-capability.js +1 -62
- package/packages/client/dist/yolo/spec-envelope-collector.js +5 -184
- package/packages/client/dist/yoloop/discovery-hook.js +2 -300
- package/packages/client/dist/yoloop/index.js +1 -8
- package/packages/client/dist/yoloop/invoke-hooks.js +12 -669
- package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1007
- package/packages/client/dist/yoloop/shared-yoloop-types.js +1 -33
- package/packages/client/dist/yoloop/target-normalization.js +1 -180
- package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1920
- package/packages/shared/dist/invocation/explicit-intent-recovery.d.ts +83 -0
- package/packages/shared/dist/invocation/explicit-intent-recovery.js +187 -0
- package/packages/shared/dist/invocation/index.d.ts +7 -0
- package/packages/shared/dist/invocation/index.js +22 -0
- package/packages/shared/dist/yolo/change-evidence.js +1 -1
- package/packages/shared/dist/yoloop/epic-terminal-git.js +144 -2
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +24 -21
- package/targets-stubs/codex/README.md +6 -1
- package/targets-stubs/codex/neocortex.toml +7 -2
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +16 -1
- package/targets-stubs/opencode/neocortex.md +6 -0
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -1,294 +1,2 @@
|
|
|
1
|
-
import { isPrivateYoloSkippedPredecessors, isPrivateQaSkippedPredecessors, isPrivateQaStructuralAdmission } from './shared-private-admission-types.js';
|
|
2
|
-
|
|
3
|
-
import { readPrivateYoloImplementationValidation } from './implementation-validation.js';
|
|
4
|
-
import { createHash } from 'node:crypto';
|
|
5
|
-
import { execFileSync } from 'node:child_process';
|
|
6
|
-
import { existsSync, lstatSync, readFileSync } from 'node:fs';
|
|
7
|
-
import { join, resolve } from 'node:path';
|
|
8
|
-
import { acquireGitLifecyclePhysicalIntegrationLock, applyGitLifecycleRuntimeOverlay, ensureGitLifecyclePrivateChildDirectory, gitLifecycleRuntimeDirectory, mutateGitLifecycleRuntime, readGitLifecycleRuntime, releaseGitLifecyclePhysicalIntegrationLock, assertGitLifecyclePrivateFile } from '../git/git-lifecycle-store.js';
|
|
9
|
-
import { anchoredAtomicWriteFile } from '../git/secure-filesystem-boundary.js';
|
|
10
|
-
import { privateYoloRootOnlySetupReady } from './clean-baseline.js';
|
|
11
|
-
import { resumePrivateYoloIsolatedSession } from './isolated-session.js';
|
|
12
|
-
const checks = ['analysisComplete', 'enrichmentReviewed', 'implementationBoundaryReviewed',
|
|
13
|
-
'dependenciesReviewed', 'smellsReviewed', 'warningsReviewed', 'mandatoryRequirementsResolved',
|
|
14
|
-
'noImplementationChange'];
|
|
15
|
-
const hash = (value) => createHash('sha256').update(value).digest('hex');
|
|
16
|
-
const profiles = {
|
|
17
|
-
diagnosis: { schema: 'PrivateYoloDiagnosisAcceptance/1', token: 'step-50224b19',
|
|
18
|
-
digest: '50224b193dae7ba2a066e54f7091d2656302b849ea7a145a3a4c556d85f3fe3c',
|
|
19
|
-
status: 'diagnose', previousStatus: 'branch-ready', predecessorCount: 1, artifact: 'diagnosis', checks },
|
|
20
|
-
research: { schema: 'PrivateYoloResearchAcceptance/1', token: 'step-f757f6bf',
|
|
21
|
-
digest: 'f757f6bf1182f23e5d7acbe47cbce9f0fa12f211d290b486892c6722bc42b4e8',
|
|
22
|
-
status: 'research', previousStatus: 'diagnose', predecessorCount: 2, artifact: 'research',
|
|
23
|
-
checks: ['researchComplete', 'officialSourcesReviewed', 'context7AvailabilityReviewed',
|
|
24
|
-
'existingPatternsReviewed', 'mockStrategyReviewed', 'requirementsTraced',
|
|
25
|
-
'mandatoryRequirementsResolved', 'noImplementationChange'] },
|
|
26
|
-
specification: { schema: 'PrivateYoloSpecificationAcceptance/1', token: 'step-9cd927d0',
|
|
27
|
-
digest: '9cd927d02ff5979b5077e75b09cb34be275eca0e1c955403235b9ba0fb7a55eb',
|
|
28
|
-
status: 'write-spec', previousStatus: 'research', predecessorCount: 3, artifact: 'spec',
|
|
29
|
-
checks: ['specificationComplete', 'acceptedResearchReviewed', 'acceptanceExamplesReviewed',
|
|
30
|
-
'contractsAndNonGoalsReviewed', 'implementationPlanReviewed', 'validationPlanReviewed',
|
|
31
|
-
'mandatoryRequirementsResolved', 'noImplementationChange'] },
|
|
32
|
-
tasks: { schema: 'PrivateYoloTasksAcceptance/1', token: 'step-a3f880e8',
|
|
33
|
-
digest: 'a3f880e8d5bca9158a88c46f88754c0948237a3e8516c83a762ba1ee22c27d46',
|
|
34
|
-
status: 'create-tasks', previousStatus: 'write-spec', predecessorCount: 4, artifact: 'tasks',
|
|
35
|
-
checks: ['tasksComplete', 'acceptedSpecificationReviewed', 'acceptanceTraceabilityReviewed',
|
|
36
|
-
'causalTestSequenceReviewed', 'implementationScopeReviewed', 'validationPlanReviewed',
|
|
37
|
-
'mandatoryRequirementsResolved', 'noImplementationChange'] },
|
|
38
|
-
implementation: { schema: 'PrivateYoloImplementationAcceptance/1', token: 'step-41803e35',
|
|
39
|
-
digest: '41803e35aae66fedeb7f3d7086f234b7d8894fa31c93088d510fd9bd1ea6a3ab', status: 'implemented', previousStatus: 'create-tasks', predecessorCount: 5,
|
|
40
|
-
artifact: 'validation-evidence', checks: ['implementationComplete', 'acceptedPlanningReviewed',
|
|
41
|
-
'acceptanceTraceabilityReviewed', 'causalTestsReviewed', 'implementationScopeReviewed',
|
|
42
|
-
'contractsReviewed', 'mandatoryRequirementsResolved', 'rootValidationReviewed'] },
|
|
43
|
-
'refactor-advisory': { schema: 'PrivateYoloRefactorAdvisoryAcceptance/1', token: 'step-fe2e4997',
|
|
44
|
-
digest: 'fe2e499748a0a6ffa5f952b0e7f6eb0f42361b6f304722aaa9eae736ca9565e7', status: 'refactor-suggest-done', previousStatus: 'implemented', predecessorCount: 6,
|
|
45
|
-
artifact: 'validation-evidence', checks: ['advisoryComplete', 'registryReviewed', 'tierAndGatesReviewed',
|
|
46
|
-
'scopeReviewed', 'suggestionsReviewed', 'nonBlockingWarningsReviewed', 'traceabilityReviewed', 'noImplementationChange'] },
|
|
47
|
-
'test-validation': { schema: 'PrivateYoloTestValidationAcceptance/1', token: 'step-b2fe7cb5',
|
|
48
|
-
digest: 'b2fe7cb5d577eecef3f9da45f9f4f11487b5a1ac27dfdf6c425a0cc5a9c9db3d', status: 'tests-validated', previousStatus: 'property-tests-emitted', predecessorCount: 8,
|
|
49
|
-
artifact: 'validation-evidence', checks: ['testCoverageComplete', 'acceptedPlanningReviewed',
|
|
50
|
-
'acceptanceTraceabilityReviewed', 'literalCommandsReviewed', 'skippedCoverageReviewed',
|
|
51
|
-
'contractsReviewed', 'mandatoryRequirementsResolved', 'rootValidationReviewed'] },
|
|
52
|
-
qa: { schema: 'PrivateYoloQaAcceptance/1', token: 'step-8721319d', digest: '8721319de90ade506bc9b72a908d8296856b34a11bc640629178bed3fe32e373',
|
|
53
|
-
status: 'qa-gate-passed', previousStatus: 'tests-validated', predecessorCount: 9, artifact: 'qa-gate-result',
|
|
54
|
-
checks: ['requirementsReviewed', 'examplesReviewed', 'contractsReviewed', 'securityAndDataReviewed',
|
|
55
|
-
'structuralIntegrityReviewed', 'skippedAndDeferredCoverageReviewed', 'findingsResolved', 'implementationScopeReviewed'] },
|
|
56
|
-
};
|
|
57
|
-
export async function acceptPrivateYoloQaRootReview(projectRoot, request) {
|
|
58
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'qa');
|
|
59
|
-
}
|
|
60
|
-
export async function acceptPrivateYoloTestValidationRootReview(projectRoot, request) {
|
|
61
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'test-validation');
|
|
62
|
-
}
|
|
63
|
-
export async function acceptPrivateYoloRefactorAdvisoryRootReview(projectRoot, request) {
|
|
64
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'refactor-advisory');
|
|
65
|
-
}
|
|
66
|
-
export async function acceptPrivateYoloImplementationRootReview(projectRoot, request) {
|
|
67
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'implementation');
|
|
68
|
-
}
|
|
69
|
-
export async function acceptPrivateYoloDiagnosisRootReview(projectRoot, request) {
|
|
70
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'diagnosis');
|
|
71
|
-
}
|
|
72
|
-
export async function acceptPrivateYoloResearchRootReview(projectRoot, request) {
|
|
73
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'research');
|
|
74
|
-
}
|
|
75
|
-
export async function acceptPrivateYoloSpecificationRootReview(projectRoot, request) {
|
|
76
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'specification');
|
|
77
|
-
}
|
|
78
|
-
export async function acceptPrivateYoloTasksRootReview(projectRoot, request) {
|
|
79
|
-
return acceptPrivateYoloAnalysisRootReview(projectRoot, request, 'tasks');
|
|
80
|
-
}
|
|
81
|
-
async function acceptPrivateYoloAnalysisRootReview(projectRoot, request, phase) {
|
|
82
|
-
const profile = profiles[phase], artifactField = `${phase}Sha256`;
|
|
83
|
-
const fail = () => { throw new Error(`private-execution-${phase}-root-review-unverified`); };
|
|
84
|
-
const record = (v) => v !== null && typeof v === 'object' && !Array.isArray(v) ? v : undefined;
|
|
85
|
-
const r = record(request), directive = record(r?.directive), review = record(r?.review);
|
|
86
|
-
const qaStructural = directive?.structuralPrecheck;
|
|
87
|
-
const equalKeys = (v, keys) => Object.keys(v).sort().join('|') === keys.sort().join('|');
|
|
88
|
-
if (!r || !directive || !review || !equalKeys(r, ['schemaVersion', 'executorStopped', 'directive', 'review'])
|
|
89
|
-
|| r.schemaVersion !== profile.schema || r.executorStopped !== true
|
|
90
|
-
|| !equalKeys(directive, ['schemaVersion', 'action', 'storyId', 'executionBranch', 'graphRevision', 'stepId', 'publicSafe', ...(phase === 'test-validation' ? ['skippedPredecessors'] : []), ...(phase === 'qa' ? ['skippedPredecessors', 'structuralPrecheck'] : [])])
|
|
91
|
-
|| directive.schemaVersion !== 1 || directive.action !== `review-${phase}-candidate`
|
|
92
|
-
|| phase === 'test-validation' && !isPrivateYoloSkippedPredecessors(directive.skippedPredecessors)
|
|
93
|
-
|| phase === 'qa' && (!isPrivateQaSkippedPredecessors(directive.skippedPredecessors)
|
|
94
|
-
|| !isPrivateQaStructuralAdmission(qaStructural)
|
|
95
|
-
|| qaStructural.graphRevision !== directive.graphRevision
|
|
96
|
-
|| directive.skippedPredecessors.some(entry => entry.tier !== qaStructural.tier))
|
|
97
|
-
|| directive.stepId !== profile.token || directive.publicSafe !== true
|
|
98
|
-
|| typeof directive.storyId !== 'string' || !/^P[1-9][0-9]*\.[0-9]+$/.test(directive.storyId)
|
|
99
|
-
|| typeof directive.graphRevision !== 'string' || !/^[a-f0-9]{64}$/.test(directive.graphRevision)
|
|
100
|
-
|| !equalKeys(review, ['reviewer', 'decision', 'snapshotSha', artifactField, 'sourceStateSha256',
|
|
101
|
-
'rawStepId', 'reviewedAt', 'checks', ...(['implementation', 'test-validation', 'qa'].includes(phase) ? ['validationReceiptId'] : []), ...(['refactor-advisory', 'test-validation', 'qa'].includes(phase) ? ['previousPhaseReceiptId'] : [])])
|
|
102
|
-
|| review.reviewer !== 'root' || review.decision !== `approve-${phase}`
|
|
103
|
-
|| typeof review.snapshotSha !== 'string' || !/^[a-f0-9]{40,64}$/.test(review.snapshotSha)
|
|
104
|
-
|| typeof review[artifactField] !== 'string' || !/^[a-f0-9]{64}$/.test(review[artifactField])
|
|
105
|
-
|| typeof review.sourceStateSha256 !== 'string' || !/^[a-f0-9]{64}$/.test(review.sourceStateSha256)
|
|
106
|
-
|| typeof review.rawStepId !== 'string'
|
|
107
|
-
|| hash(review.rawStepId) !== profile.digest
|
|
108
|
-
|| typeof review.reviewedAt !== 'string' || !Number.isFinite(Date.parse(review.reviewedAt))
|
|
109
|
-
|| Date.parse(review.reviewedAt) > Date.now() || Date.now() - Date.parse(review.reviewedAt) > 10 * 60_000
|
|
110
|
-
|| !record(review.checks) || !equalKeys(record(review.checks), [...profile.checks])
|
|
111
|
-
|| profile.checks.some(key => record(review.checks)[key] !== true))
|
|
112
|
-
fail();
|
|
113
|
-
const skippedProperty = phase === 'test-validation' && directive.skippedPredecessors.length === 1;
|
|
114
|
-
const predecessorCount = profile.predecessorCount - (skippedProperty ? 1 : 0);
|
|
115
|
-
const previousStatus = skippedProperty ? 'refactor-suggest-done' : profile.previousStatus;
|
|
116
|
-
let qaPredecessor;
|
|
117
|
-
let qaOptionalDebt = [];
|
|
118
|
-
const root = resolve(projectRoot), storyId = directive.storyId;
|
|
119
|
-
const graphRevision = directive.graphRevision, epicId = storyId.split('.')[0];
|
|
120
|
-
const before = await readGitLifecycleRuntime(root, { required: true });
|
|
121
|
-
const epic = before.epics[epicId], lease = record(epic?.branch_lease);
|
|
122
|
-
if (!lease || typeof lease.sessionId !== 'string' || lease.ownerStoryId !== storyId
|
|
123
|
-
|| lease.idempotencyKey !== lease.sessionId || epic?.graph_revision !== graphRevision
|
|
124
|
-
|| typeof lease.expiresAt !== 'string' || !Number.isFinite(Date.parse(lease.expiresAt))
|
|
125
|
-
|| Date.parse(lease.expiresAt) <= Date.now())
|
|
126
|
-
fail();
|
|
127
|
-
const lock = await acquireGitLifecyclePhysicalIntegrationLock(root, { kind: 'direct', storyId,
|
|
128
|
-
sessionId: lease.sessionId, idempotencyKey: lease.sessionId,
|
|
129
|
-
expiresAt: new Date(Date.now() + 5 * 60_000).toISOString(), persistent: false });
|
|
130
|
-
if (!lock.ok)
|
|
131
|
-
throw new Error(`private-execution-${phase}-root-review-unverified`);
|
|
132
|
-
try {
|
|
133
|
-
const verify = async () => {
|
|
134
|
-
const session = await resumePrivateYoloIsolatedSession(root, storyId, graphRevision);
|
|
135
|
-
if (session.snapshotSha !== review.snapshotSha || session.sequence < 1
|
|
136
|
-
|| session.workspace.executionBranch !== directive.executionBranch)
|
|
137
|
-
fail();
|
|
138
|
-
const sourceState = JSON.parse(readFileSync(join(root, '.neocortex/state.json'), 'utf8'));
|
|
139
|
-
const implementationClaim = profile.predecessorCount >= 5 ? sourceState.stories?.[storyId]?.files_to_modify : [];
|
|
140
|
-
if (!Array.isArray(implementationClaim) || implementationClaim.some((p) => typeof p !== 'string'))
|
|
141
|
-
fail();
|
|
142
|
-
const allowed = [...implementationClaim, '.neocortex/state.json', `docs/stories/${storyId}.story.md`,
|
|
143
|
-
`.neocortex/stories/${storyId}/diagnosis.md`, `.neocortex/stories/${storyId}/diagnose.md`,
|
|
144
|
-
...(profile.predecessorCount >= 2 ? [`.neocortex/stories/${storyId}/research.md`, `docs/stories/${storyId}.research.md`] : []),
|
|
145
|
-
...(profile.predecessorCount >= 3 ? [`docs/stories/${storyId}.spec.md`, `docs/stories/${storyId}.rtm.md`] : []),
|
|
146
|
-
...(profile.predecessorCount >= 4 ? [`docs/stories/${storyId}.tasks.md`] : [])];
|
|
147
|
-
const delta = execFileSync('git', ['diff', '--name-only', '-z', session.workspace.baseSha, session.snapshotSha, '--'], {
|
|
148
|
-
cwd: session.workspace.workspacePath,
|
|
149
|
-
env: Object.fromEntries(Object.entries(process.env).filter(([key]) => !key.startsWith('GIT_'))),
|
|
150
|
-
encoding: 'utf8', timeout: 30_000, maxBuffer: 1024 * 1024,
|
|
151
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
152
|
-
}).split('\0').filter(Boolean);
|
|
153
|
-
if (delta.some(path => !allowed.includes(path)))
|
|
154
|
-
fail();
|
|
155
|
-
const path = phase === 'qa' ? join(root, '.neocortex', 'stories', storyId, 'qa-gate-result.json') : profile.artifact === 'validation-evidence' ? join(root, '.neocortex', 'stories', storyId, 'validation-evidence.md') : profile.predecessorCount < 3
|
|
156
|
-
? join(root, '.neocortex', 'stories', storyId, `${profile.artifact}.md`)
|
|
157
|
-
: join(root, 'docs', 'stories', `${storyId}.${profile.artifact}.md`);
|
|
158
|
-
const file = lstatSync(path);
|
|
159
|
-
if (!file.isFile() || file.isSymbolicLink() || file.nlink !== 1 || file.size < 128 || file.size > 256 * 1024
|
|
160
|
-
|| hash(readFileSync(path)) !== review[artifactField]
|
|
161
|
-
|| hash(readFileSync(join(root, '.neocortex/state.json'))) !== review.sourceStateSha256)
|
|
162
|
-
fail();
|
|
163
|
-
if (profile.predecessorCount >= 5) {
|
|
164
|
-
const baselineState = execFileSync('git', ['show', `${session.workspace.baseSha}:.neocortex/state.json`], { cwd: session.workspace.workspacePath, timeout: 30_000, stdio: ['ignore', 'pipe', 'ignore'] });
|
|
165
|
-
if (!baselineState.equals(readFileSync(join(root, '.neocortex/state.json'))))
|
|
166
|
-
fail();
|
|
167
|
-
execFileSync('git', ['diff', '--check', session.workspace.baseSha, session.snapshotSha], { cwd: session.workspace.workspacePath, timeout: 30_000, stdio: 'ignore' });
|
|
168
|
-
if (phase === 'implementation' || phase === 'test-validation' || phase === 'qa')
|
|
169
|
-
await readPrivateYoloImplementationValidation(root, review.validationReceiptId, { storyId, graphRevision, snapshotSha: session.snapshotSha, sourceHeadSha: session.workspace.baseSha });
|
|
170
|
-
if (phase === 'refactor-advisory' || phase === 'test-validation' || phase === 'qa') {
|
|
171
|
-
const id = review.previousPhaseReceiptId;
|
|
172
|
-
if (typeof id !== 'string' || !/^[a-f0-9]{64}$/.test(id))
|
|
173
|
-
fail();
|
|
174
|
-
const parent = await ensureGitLifecyclePrivateChildDirectory(await gitLifecycleRuntimeDirectory(root), 'private-execution');
|
|
175
|
-
const qaSkips = phase === 'qa' ? directive.skippedPredecessors : [];
|
|
176
|
-
const qaSkippedTests = qaSkips.some(entry => entry.stepId === 'step-b2fe7cb5');
|
|
177
|
-
const qaSkippedProperty = qaSkips.some(entry => entry.stepId === 'step-a8ce5c64');
|
|
178
|
-
const previousPhase = phase === 'qa' ? qaSkippedTests ? qaSkippedProperty ? 'refactor-advisory' : 'property-tests' : 'test-validation'
|
|
179
|
-
: phase === 'refactor-advisory' ? 'implementation' : skippedProperty ? 'refactor-advisory' : 'property-tests';
|
|
180
|
-
const predecessorPath = join(parent, `${previousPhase}-review-${id}.json`);
|
|
181
|
-
await assertGitLifecyclePrivateFile(predecessorPath, parent);
|
|
182
|
-
const bytes = readFileSync(predecessorPath);
|
|
183
|
-
if (bytes.length > 16384 || hash(bytes) !== id)
|
|
184
|
-
fail();
|
|
185
|
-
const predecessor = JSON.parse(bytes.toString());
|
|
186
|
-
if (predecessor.kind !== `private-${previousPhase}-root-review` || predecessor.storyId !== storyId
|
|
187
|
-
|| predecessor.sourceHeadSha !== session.workspace.baseSha || !/^[a-f0-9]{40,64}$/.test(predecessor.snapshotSha)
|
|
188
|
-
|| predecessor.independentStoryQaAccepted !== false || predecessor.terminalAccepted !== false)
|
|
189
|
-
fail();
|
|
190
|
-
const git = (...args) => execFileSync('git', args, { cwd: session.workspace.workspacePath, timeout: 30_000, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
191
|
-
git('merge-base', '--is-ancestor', predecessor.snapshotSha, session.snapshotSha);
|
|
192
|
-
const changes = git('diff', '--name-only', '-z', predecessor.snapshotSha, session.snapshotSha).split('\0').filter(Boolean);
|
|
193
|
-
const metadata = [...(phase === 'qa' ? [`.neocortex/stories/${storyId}/qa-gate-result.json`] : []), `.neocortex/stories/${storyId}/validation-evidence.md`, `.neocortex/stories/${storyId}/tdd-evidence.md`, `docs/stories/${storyId}.rtm.md`];
|
|
194
|
-
if (changes.some(path => !metadata.includes(path)))
|
|
195
|
-
fail();
|
|
196
|
-
if (phase === 'qa') {
|
|
197
|
-
if (!qaSkippedTests && !isPrivateYoloSkippedPredecessors(predecessor.skippedPredecessors))
|
|
198
|
-
fail();
|
|
199
|
-
const propertyWasSkipped = qaSkippedTests ? qaSkippedProperty : predecessor.skippedPredecessors.length === 1;
|
|
200
|
-
const digests = [...['diagnosis', 'research', 'specification', 'tasks', 'implementation', 'refactor-advisory'].map(key => profiles[key].digest),
|
|
201
|
-
...(propertyWasSkipped ? [] : ['a8ce5c6462803364cabab06cd41304a578ca2f1d50627c7f162020159670dedf']), ...(qaSkippedTests ? [] : [profiles['test-validation'].digest])];
|
|
202
|
-
qaPredecessor = { digests, count: digests.length + 1, status: qaSkippedTests ? qaSkippedProperty ? 'refactor-suggest-done' : 'property-tests-emitted' : 'tests-validated' };
|
|
203
|
-
const local = await readPrivateYoloImplementationValidation(root, review.validationReceiptId, { storyId, graphRevision, snapshotSha: session.snapshotSha, sourceHeadSha: session.workspace.baseSha });
|
|
204
|
-
if (local.structuralIntegrity?.schemaVersion !== 1 || local.structuralIntegrity?.scope !== 'project-snapshot'
|
|
205
|
-
|| local.structuralIntegrity.canonicalStateParsed !== true || local.structuralIntegrity.trackedInputsUnchanged !== true)
|
|
206
|
-
fail();
|
|
207
|
-
const candidate = JSON.parse(readFileSync(path, 'utf8'));
|
|
208
|
-
if (candidate.schemaVersion !== 3 || candidate.candidate !== true || candidate.stageComplete !== false
|
|
209
|
-
|| candidate.status !== 'qa-review-pending' || candidate.independentStoryQaAccepted !== false
|
|
210
|
-
|| !Array.isArray(candidate.blockingChecks) || candidate.blockingChecks.length !== 0
|
|
211
|
-
|| !isPrivateQaStructuralAdmission(candidate.structuralPrecheck)
|
|
212
|
-
|| ['schemaVersion', 'kind', 'stepId', 'generationId', 'graphRevision', 'topologyGenerationId', 'tier', 'publicSafe'].some(key => candidate.structuralPrecheck[key] !== directive.structuralPrecheck[key])
|
|
213
|
-
|| !Array.isArray(candidate.followUpDebt) || candidate.followUpDebt.length > 50)
|
|
214
|
-
fail();
|
|
215
|
-
for (const item of candidate.followUpDebt) {
|
|
216
|
-
const debt = record(item);
|
|
217
|
-
if (!debt || !equalKeys(debt, ['id', 'reasonCode', 'ownerArea', 'severity', 'description', 'trigger', 'publicSafe'])
|
|
218
|
-
|| debt.publicSafe !== true || !['P2', 'P3'].includes(String(debt.severity))
|
|
219
|
-
|| ['id', 'reasonCode', 'ownerArea', 'description', 'trigger'].some(key => typeof debt[key] !== 'string' || debt[key].length < 1 || debt[key].length > 1000))
|
|
220
|
-
fail();
|
|
221
|
-
}
|
|
222
|
-
qaOptionalDebt = candidate.followUpDebt;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
if (phase === 'tasks' || profile.predecessorCount >= 5) {
|
|
227
|
-
const matrix = lstatSync(join(root, 'docs/stories', `${storyId}.rtm.md`));
|
|
228
|
-
if (!matrix.isFile() || matrix.isSymbolicLink() || matrix.nlink !== 1 || matrix.size < 128
|
|
229
|
-
|| matrix.size > 256 * 1024)
|
|
230
|
-
fail();
|
|
231
|
-
}
|
|
232
|
-
return session;
|
|
233
|
-
};
|
|
234
|
-
const session = await verify();
|
|
235
|
-
const state = JSON.parse(readFileSync(join(root, '.neocortex/state.json'), 'utf8'));
|
|
236
|
-
const effective = applyGitLifecycleRuntimeOverlay(state, before);
|
|
237
|
-
const story = record(record(effective.stories)?.[storyId]);
|
|
238
|
-
if (!story || story.checkpoint !== undefined)
|
|
239
|
-
fail();
|
|
240
|
-
const rawStepId = review.rawStepId;
|
|
241
|
-
const predecessorReady = (candidate) => {
|
|
242
|
-
if (phase === 'diagnosis')
|
|
243
|
-
return privateYoloRootOnlySetupReady(candidate);
|
|
244
|
-
const steps = candidate.steps_completed;
|
|
245
|
-
const predecessorDigests = [...['diagnosis', 'research', 'specification', 'tasks', 'implementation', 'refactor-advisory'].map(key => profiles[key].digest), 'a8ce5c6462803364cabab06cd41304a578ca2f1d50627c7f162020159670dedf'];
|
|
246
|
-
if (phase === 'qa' && !qaPredecessor)
|
|
247
|
-
return false;
|
|
248
|
-
const requiredStatus = phase === 'qa' ? qaPredecessor.status : previousStatus;
|
|
249
|
-
const requiredCount = phase === 'qa' ? qaPredecessor.count : predecessorCount;
|
|
250
|
-
const requiredDigests = phase === 'qa' ? qaPredecessor.digests : predecessorDigests;
|
|
251
|
-
return candidate.status === requiredStatus && Array.isArray(steps) && steps.length === requiredCount
|
|
252
|
-
&& candidate.last_step === steps.at(-1)
|
|
253
|
-
&& steps.slice(1).every((step, index) => typeof step === 'string' && hash(step) === requiredDigests[index])
|
|
254
|
-
&& privateYoloRootOnlySetupReady({ status: 'branch-ready', last_step: steps[0], steps_completed: [steps[0]] });
|
|
255
|
-
};
|
|
256
|
-
const completed = story.steps_completed;
|
|
257
|
-
const replay = story?.status === profile.status && story.last_step === rawStepId
|
|
258
|
-
&& Array.isArray(completed) && completed.length === (phase === 'qa' ? qaPredecessor.count : predecessorCount) + 1
|
|
259
|
-
&& completed.at(-1) === rawStepId
|
|
260
|
-
&& predecessorReady({ status: phase === 'qa' ? qaPredecessor.status : previousStatus, last_step: completed.at(-2), steps_completed: completed.slice(0, -1) });
|
|
261
|
-
if (!replay && !predecessorReady(story))
|
|
262
|
-
fail();
|
|
263
|
-
const receipt = { schemaVersion: 1, kind: `private-${phase}-root-review`, storyId, graphRevision,
|
|
264
|
-
sourceHeadSha: session.workspace.baseSha, snapshotSha: session.snapshotSha,
|
|
265
|
-
[artifactField]: review[artifactField], sourceStateSha256: review.sourceStateSha256,
|
|
266
|
-
reviewedAt: review.reviewedAt, checks: review.checks, ...(['implementation', 'test-validation', 'qa'].includes(phase) ? { validationReceiptId: review.validationReceiptId } : {}), ...(['refactor-advisory', 'test-validation', 'qa'].includes(phase) ? { previousPhaseReceiptId: review.previousPhaseReceiptId } : {}), ...(['test-validation', 'qa'].includes(phase) ? { skippedPredecessors: directive.skippedPredecessors } : {}), ...(phase === 'qa' ? { structuralPrecheck: directive.structuralPrecheck, precommitQaAccepted: true, optionalDebt: qaOptionalDebt } : {}), independentStoryQaAccepted: false,
|
|
267
|
-
terminalAccepted: false };
|
|
268
|
-
const bytes = JSON.stringify(receipt) + '\n', receiptId = hash(bytes);
|
|
269
|
-
const parent = await ensureGitLifecyclePrivateChildDirectory(await gitLifecycleRuntimeDirectory(root), 'private-execution');
|
|
270
|
-
const receiptName = `${phase}-review-${receiptId}.json`;
|
|
271
|
-
if (existsSync(join(parent, receiptName))) {
|
|
272
|
-
await assertGitLifecyclePrivateFile(join(parent, receiptName), parent);
|
|
273
|
-
if (readFileSync(join(parent, receiptName), 'utf8') !== bytes)
|
|
274
|
-
fail();
|
|
275
|
-
}
|
|
276
|
-
else
|
|
277
|
-
await anchoredAtomicWriteFile(parent, receiptName, bytes);
|
|
278
|
-
if (!replay)
|
|
279
|
-
await mutateGitLifecycleRuntime(root, document => {
|
|
280
|
-
if (JSON.stringify(document.epics[epicId]) !== JSON.stringify(epic)
|
|
281
|
-
|| JSON.stringify(document.stories[storyId]) !== JSON.stringify(before.stories[storyId]))
|
|
282
|
-
fail();
|
|
283
|
-
document.stories[storyId] = { ...document.stories[storyId], status: profile.status,
|
|
284
|
-
last_step: rawStepId, steps_completed: [...story.steps_completed, rawStepId] };
|
|
285
|
-
}, { expectedRevision: before.revision, preCommit: async () => { await verify(); } });
|
|
286
|
-
return { schemaVersion: 1, outcome: `${phase}-root-accepted`, storyId, graphRevision,
|
|
287
|
-
receiptId, snapshotSha: session.snapshotSha, reused: replay, sourceStateUnchanged: true, ...(phase === 'qa' ? { precommitQaAccepted: true } : {}),
|
|
288
|
-
independentStoryQaAccepted: false, terminalAccepted: false, publicSafe: true };
|
|
289
|
-
}
|
|
290
|
-
finally {
|
|
291
|
-
if (!await releaseGitLifecyclePhysicalIntegrationLock(lock.path, lock.owner))
|
|
292
|
-
fail();
|
|
293
|
-
}
|
|
294
|
-
}
|
|
1
|
+
import{isPrivateYoloSkippedPredecessors as ue,isPrivateQaSkippedPredecessors as qe,isPrivateQaStructuralAdmission as ve}from"./shared-private-admission-types.js";import{readPrivateYoloImplementationValidation as me}from"./implementation-validation.js";import{createHash as Ae}from"node:crypto";import{execFileSync as F}from"node:child_process";import{existsSync as xe,lstatSync as ye,readFileSync as S}from"node:fs";import{join as u,resolve as Ce}from"node:path";import{acquireGitLifecyclePhysicalIntegrationLock as $e,applyGitLifecycleRuntimeOverlay as De,ensureGitLifecyclePrivateChildDirectory as he,gitLifecycleRuntimeDirectory as we,mutateGitLifecycleRuntime as _e,readGitLifecycleRuntime as Ye,releaseGitLifecyclePhysicalIntegrationLock as je,assertGitLifecyclePrivateFile as ge}from"../git/git-lifecycle-store.js";import{anchoredAtomicWriteFile as Oe}from"../git/secure-filesystem-boundary.js";import{privateYoloRootOnlySetupReady as Se}from"./clean-baseline.js";import{resumePrivateYoloIsolatedSession as Ve}from"./isolated-session.js";const Ne=["analysisComplete","enrichmentReviewed","implementationBoundaryReviewed","dependenciesReviewed","smellsReviewed","warningsReviewed","mandatoryRequirementsResolved","noImplementationChange"],C=r=>Ae("sha256").update(r).digest("hex"),J={diagnosis:{schema:"PrivateYoloDiagnosisAcceptance/1",token:"step-50224b19",digest:"50224b193dae7ba2a066e54f7091d2656302b849ea7a145a3a4c556d85f3fe3c",status:"diagnose",previousStatus:"branch-ready",predecessorCount:1,artifact:"diagnosis",checks:Ne},research:{schema:"PrivateYoloResearchAcceptance/1",token:"step-f757f6bf",digest:"f757f6bf1182f23e5d7acbe47cbce9f0fa12f211d290b486892c6722bc42b4e8",status:"research",previousStatus:"diagnose",predecessorCount:2,artifact:"research",checks:["researchComplete","officialSourcesReviewed","context7AvailabilityReviewed","existingPatternsReviewed","mockStrategyReviewed","requirementsTraced","mandatoryRequirementsResolved","noImplementationChange"]},specification:{schema:"PrivateYoloSpecificationAcceptance/1",token:"step-9cd927d0",digest:"9cd927d02ff5979b5077e75b09cb34be275eca0e1c955403235b9ba0fb7a55eb",status:"write-spec",previousStatus:"research",predecessorCount:3,artifact:"spec",checks:["specificationComplete","acceptedResearchReviewed","acceptanceExamplesReviewed","contractsAndNonGoalsReviewed","implementationPlanReviewed","validationPlanReviewed","mandatoryRequirementsResolved","noImplementationChange"]},tasks:{schema:"PrivateYoloTasksAcceptance/1",token:"step-a3f880e8",digest:"a3f880e8d5bca9158a88c46f88754c0948237a3e8516c83a762ba1ee22c27d46",status:"create-tasks",previousStatus:"write-spec",predecessorCount:4,artifact:"tasks",checks:["tasksComplete","acceptedSpecificationReviewed","acceptanceTraceabilityReviewed","causalTestSequenceReviewed","implementationScopeReviewed","validationPlanReviewed","mandatoryRequirementsResolved","noImplementationChange"]},implementation:{schema:"PrivateYoloImplementationAcceptance/1",token:"step-41803e35",digest:"41803e35aae66fedeb7f3d7086f234b7d8894fa31c93088d510fd9bd1ea6a3ab",status:"implemented",previousStatus:"create-tasks",predecessorCount:5,artifact:"validation-evidence",checks:["implementationComplete","acceptedPlanningReviewed","acceptanceTraceabilityReviewed","causalTestsReviewed","implementationScopeReviewed","contractsReviewed","mandatoryRequirementsResolved","rootValidationReviewed"]},"refactor-advisory":{schema:"PrivateYoloRefactorAdvisoryAcceptance/1",token:"step-fe2e4997",digest:"fe2e499748a0a6ffa5f952b0e7f6eb0f42361b6f304722aaa9eae736ca9565e7",status:"refactor-suggest-done",previousStatus:"implemented",predecessorCount:6,artifact:"validation-evidence",checks:["advisoryComplete","registryReviewed","tierAndGatesReviewed","scopeReviewed","suggestionsReviewed","nonBlockingWarningsReviewed","traceabilityReviewed","noImplementationChange"]},"test-validation":{schema:"PrivateYoloTestValidationAcceptance/1",token:"step-b2fe7cb5",digest:"b2fe7cb5d577eecef3f9da45f9f4f11487b5a1ac27dfdf6c425a0cc5a9c9db3d",status:"tests-validated",previousStatus:"property-tests-emitted",predecessorCount:8,artifact:"validation-evidence",checks:["testCoverageComplete","acceptedPlanningReviewed","acceptanceTraceabilityReviewed","literalCommandsReviewed","skippedCoverageReviewed","contractsReviewed","mandatoryRequirementsResolved","rootValidationReviewed"]},qa:{schema:"PrivateYoloQaAcceptance/1",token:"step-8721319d",digest:"8721319de90ade506bc9b72a908d8296856b34a11bc640629178bed3fe32e373",status:"qa-gate-passed",previousStatus:"tests-validated",predecessorCount:9,artifact:"qa-gate-result",checks:["requirementsReviewed","examplesReviewed","contractsReviewed","securityAndDataReviewed","structuralIntegrityReviewed","skippedAndDeferredCoverageReviewed","findingsResolved","implementationScopeReviewed"]}};async function Ee(r,n){return R(r,n,"qa")}async function We(r,n){return R(r,n,"test-validation")}async function Ke(r,n){return R(r,n,"refactor-advisory")}async function Me(r,n){return R(r,n,"implementation")}async function Xe(r,n){return R(r,n,"diagnosis")}async function Ze(r,n){return R(r,n,"research")}async function et(r,n){return R(r,n,"specification")}async function tt(r,n){return R(r,n,"tasks")}async function R(r,n,e){const c=J[e],I=`${e}Sha256`,o=()=>{throw new Error(`private-execution-${e}-root-review-unverified`)},v=l=>l!==null&&typeof l=="object"&&!Array.isArray(l)?l:void 0,q=v(n),a=v(q?.directive),t=v(q?.review),B=a?.structuralPrecheck,$=(l,D)=>Object.keys(l).sort().join("|")===D.sort().join("|");(!q||!a||!t||!$(q,["schemaVersion","executorStopped","directive","review"])||q.schemaVersion!==c.schema||q.executorStopped!==!0||!$(a,["schemaVersion","action","storyId","executionBranch","graphRevision","stepId","publicSafe",...e==="test-validation"?["skippedPredecessors"]:[],...e==="qa"?["skippedPredecessors","structuralPrecheck"]:[]])||a.schemaVersion!==1||a.action!==`review-${e}-candidate`||e==="test-validation"&&!ue(a.skippedPredecessors)||e==="qa"&&(!qe(a.skippedPredecessors)||!ve(B)||B.graphRevision!==a.graphRevision||a.skippedPredecessors.some(l=>l.tier!==B.tier))||a.stepId!==c.token||a.publicSafe!==!0||typeof a.storyId!="string"||!/^P[1-9][0-9]*\.[0-9]+$/.test(a.storyId)||typeof a.graphRevision!="string"||!/^[a-f0-9]{64}$/.test(a.graphRevision)||!$(t,["reviewer","decision","snapshotSha",I,"sourceStateSha256","rawStepId","reviewedAt","checks",...["implementation","test-validation","qa"].includes(e)?["validationReceiptId"]:[],...["refactor-advisory","test-validation","qa"].includes(e)?["previousPhaseReceiptId"]:[]])||t.reviewer!=="root"||t.decision!==`approve-${e}`||typeof t.snapshotSha!="string"||!/^[a-f0-9]{40,64}$/.test(t.snapshotSha)||typeof t[I]!="string"||!/^[a-f0-9]{64}$/.test(t[I])||typeof t.sourceStateSha256!="string"||!/^[a-f0-9]{64}$/.test(t.sourceStateSha256)||typeof t.rawStepId!="string"||C(t.rawStepId)!==c.digest||typeof t.reviewedAt!="string"||!Number.isFinite(Date.parse(t.reviewedAt))||Date.parse(t.reviewedAt)>Date.now()||Date.now()-Date.parse(t.reviewedAt)>10*6e4||!v(t.checks)||!$(v(t.checks),[...c.checks])||c.checks.some(l=>v(t.checks)[l]!==!0))&&o();const z=e==="test-validation"&&a.skippedPredecessors.length===1,ee=c.predecessorCount-(z?1:0),te=z?"refactor-suggest-done":c.previousStatus;let k,se=[];const d=Ce(r),s=a.storyId,A=a.graphRevision,ie=s.split(".")[0],N=await Ye(d,{required:!0}),U=N.epics[ie],m=v(U?.branch_lease);(!m||typeof m.sessionId!="string"||m.ownerStoryId!==s||m.idempotencyKey!==m.sessionId||U?.graph_revision!==A||typeof m.expiresAt!="string"||!Number.isFinite(Date.parse(m.expiresAt))||Date.parse(m.expiresAt)<=Date.now())&&o();const H=await $e(d,{kind:"direct",storyId:s,sessionId:m.sessionId,idempotencyKey:m.sessionId,expiresAt:new Date(Date.now()+5*6e4).toISOString(),persistent:!1});if(!H.ok)throw new Error(`private-execution-${e}-root-review-unverified`);try{const l=async()=>{const i=await Ve(d,s,A);(i.snapshotSha!==t.snapshotSha||i.sequence<1||i.workspace.executionBranch!==a.executionBranch)&&o();const g=JSON.parse(S(u(d,".neocortex/state.json"),"utf8")),j=c.predecessorCount>=5?g.stories?.[s]?.files_to_modify:[];(!Array.isArray(j)||j.some(p=>typeof p!="string"))&&o();const K=[...j,".neocortex/state.json",`docs/stories/${s}.story.md`,`.neocortex/stories/${s}/diagnosis.md`,`.neocortex/stories/${s}/diagnose.md`,...c.predecessorCount>=2?[`.neocortex/stories/${s}/research.md`,`docs/stories/${s}.research.md`]:[],...c.predecessorCount>=3?[`docs/stories/${s}.spec.md`,`docs/stories/${s}.rtm.md`]:[],...c.predecessorCount>=4?[`docs/stories/${s}.tasks.md`]:[]];F("git",["diff","--name-only","-z",i.workspace.baseSha,i.snapshotSha,"--"],{cwd:i.workspace.workspacePath,env:Object.fromEntries(Object.entries(process.env).filter(([p])=>!p.startsWith("GIT_"))),encoding:"utf8",timeout:3e4,maxBuffer:1024*1024,stdio:["ignore","pipe","ignore"]}).split("\0").filter(Boolean).some(p=>!K.includes(p))&&o();const O=e==="qa"?u(d,".neocortex","stories",s,"qa-gate-result.json"):c.artifact==="validation-evidence"?u(d,".neocortex","stories",s,"validation-evidence.md"):c.predecessorCount<3?u(d,".neocortex","stories",s,`${c.artifact}.md`):u(d,"docs","stories",`${s}.${c.artifact}.md`),y=ye(O);if((!y.isFile()||y.isSymbolicLink()||y.nlink!==1||y.size<128||y.size>262144||C(S(O))!==t[I]||C(S(u(d,".neocortex/state.json")))!==t.sourceStateSha256)&&o(),c.predecessorCount>=5&&(F("git",["show",`${i.workspace.baseSha}:.neocortex/state.json`],{cwd:i.workspace.workspacePath,timeout:3e4,stdio:["ignore","pipe","ignore"]}).equals(S(u(d,".neocortex/state.json")))||o(),F("git",["diff","--check",i.workspace.baseSha,i.snapshotSha],{cwd:i.workspace.workspacePath,timeout:3e4,stdio:"ignore"}),(e==="implementation"||e==="test-validation"||e==="qa")&&await me(d,t.validationReceiptId,{storyId:s,graphRevision:A,snapshotSha:i.snapshotSha,sourceHeadSha:i.workspace.baseSha}),e==="refactor-advisory"||e==="test-validation"||e==="qa")){const G=t.previousPhaseReceiptId;(typeof G!="string"||!/^[a-f0-9]{64}$/.test(G))&&o();const ce=await he(await we(d),"private-execution"),ne=e==="qa"?a.skippedPredecessors:[],V=ne.some(w=>w.stepId==="step-b2fe7cb5"),M=ne.some(w=>w.stepId==="step-a8ce5c64"),de=e==="qa"?V?M?"refactor-advisory":"property-tests":"test-validation":e==="refactor-advisory"?"implementation":z?"refactor-advisory":"property-tests",pe=u(ce,`${de}-review-${G}.json`);await ge(pe,ce);const X=S(pe);(X.length>16384||C(X)!==G)&&o();const h=JSON.parse(X.toString());(h.kind!==`private-${de}-root-review`||h.storyId!==s||h.sourceHeadSha!==i.workspace.baseSha||!/^[a-f0-9]{40,64}$/.test(h.snapshotSha)||h.independentStoryQaAccepted!==!1||h.terminalAccepted!==!1)&&o();const le=(...w)=>F("git",w,{cwd:i.workspace.workspacePath,timeout:3e4,encoding:"utf8",stdio:["ignore","pipe","ignore"]});le("merge-base","--is-ancestor",h.snapshotSha,i.snapshotSha);const Pe=le("diff","--name-only","-z",h.snapshotSha,i.snapshotSha).split("\0").filter(Boolean),Ie=[...e==="qa"?[`.neocortex/stories/${s}/qa-gate-result.json`]:[],`.neocortex/stories/${s}/validation-evidence.md`,`.neocortex/stories/${s}/tdd-evidence.md`,`docs/stories/${s}.rtm.md`];if(Pe.some(w=>!Ie.includes(w))&&o(),e==="qa"){!V&&!ue(h.skippedPredecessors)&&o();const w=V?M:h.skippedPredecessors.length===1,fe=[...["diagnosis","research","specification","tasks","implementation","refactor-advisory"].map(x=>J[x].digest),...w?[]:["a8ce5c6462803364cabab06cd41304a578ca2f1d50627c7f162020159670dedf"],...V?[]:[J["test-validation"].digest]];k={digests:fe,count:fe.length+1,status:V?M?"refactor-suggest-done":"property-tests-emitted":"tests-validated"};const Q=await me(d,t.validationReceiptId,{storyId:s,graphRevision:A,snapshotSha:i.snapshotSha,sourceHeadSha:i.workspace.baseSha});(Q.structuralIntegrity?.schemaVersion!==1||Q.structuralIntegrity?.scope!=="project-snapshot"||Q.structuralIntegrity.canonicalStateParsed!==!0||Q.structuralIntegrity.trackedInputsUnchanged!==!0)&&o();const f=JSON.parse(S(O,"utf8"));(f.schemaVersion!==3||f.candidate!==!0||f.stageComplete!==!1||f.status!=="qa-review-pending"||f.independentStoryQaAccepted!==!1||!Array.isArray(f.blockingChecks)||f.blockingChecks.length!==0||!ve(f.structuralPrecheck)||["schemaVersion","kind","stepId","generationId","graphRevision","topologyGenerationId","tier","publicSafe"].some(x=>f.structuralPrecheck[x]!==a.structuralPrecheck[x])||!Array.isArray(f.followUpDebt)||f.followUpDebt.length>50)&&o();for(const x of f.followUpDebt){const P=v(x);(!P||!$(P,["id","reasonCode","ownerArea","severity","description","trigger","publicSafe"])||P.publicSafe!==!0||!["P2","P3"].includes(String(P.severity))||["id","reasonCode","ownerArea","description","trigger"].some(Z=>typeof P[Z]!="string"||P[Z].length<1||P[Z].length>1e3))&&o()}se=f.followUpDebt}}if(e==="tasks"||c.predecessorCount>=5){const p=ye(u(d,"docs/stories",`${s}.rtm.md`));(!p.isFile()||p.isSymbolicLink()||p.nlink!==1||p.size<128||p.size>262144)&&o()}return i},D=await l(),Re=JSON.parse(S(u(d,".neocortex/state.json"),"utf8")),ke=De(Re,N),b=v(v(ke.stories)?.[s]);(!b||b.checkpoint!==void 0)&&o();const L=t.rawStepId,ae=i=>{if(e==="diagnosis")return Se(i);const g=i.steps_completed,j=[...["diagnosis","research","specification","tasks","implementation","refactor-advisory"].map(y=>J[y].digest),"a8ce5c6462803364cabab06cd41304a578ca2f1d50627c7f162020159670dedf"];if(e==="qa"&&!k)return!1;const K=e==="qa"?k.status:te,re=e==="qa"?k.count:ee,O=e==="qa"?k.digests:j;return i.status===K&&Array.isArray(g)&&g.length===re&&i.last_step===g.at(-1)&&g.slice(1).every((y,p)=>typeof y=="string"&&C(y)===O[p])&&Se({status:"branch-ready",last_step:g[0],steps_completed:[g[0]]})},_=b.steps_completed,E=b?.status===c.status&&b.last_step===L&&Array.isArray(_)&&_.length===(e==="qa"?k.count:ee)+1&&_.at(-1)===L&&ae({status:e==="qa"?k.status:te,last_step:_.at(-2),steps_completed:_.slice(0,-1)});!E&&!ae(b)&&o();const be={schemaVersion:1,kind:`private-${e}-root-review`,storyId:s,graphRevision:A,sourceHeadSha:D.workspace.baseSha,snapshotSha:D.snapshotSha,[I]:t[I],sourceStateSha256:t.sourceStateSha256,reviewedAt:t.reviewedAt,checks:t.checks,...["implementation","test-validation","qa"].includes(e)?{validationReceiptId:t.validationReceiptId}:{},...["refactor-advisory","test-validation","qa"].includes(e)?{previousPhaseReceiptId:t.previousPhaseReceiptId}:{},...["test-validation","qa"].includes(e)?{skippedPredecessors:a.skippedPredecessors}:{},...e==="qa"?{structuralPrecheck:a.structuralPrecheck,precommitQaAccepted:!0,optionalDebt:se}:{},independentStoryQaAccepted:!1,terminalAccepted:!1},W=JSON.stringify(be)+`
|
|
2
|
+
`,oe=C(W),Y=await he(await we(d),"private-execution"),T=`${e}-review-${oe}.json`;return xe(u(Y,T))?(await ge(u(Y,T),Y),S(u(Y,T),"utf8")!==W&&o()):await Oe(Y,T,W),E||await _e(d,i=>{(JSON.stringify(i.epics[ie])!==JSON.stringify(U)||JSON.stringify(i.stories[s])!==JSON.stringify(N.stories[s]))&&o(),i.stories[s]={...i.stories[s],status:c.status,last_step:L,steps_completed:[...b.steps_completed,L]}},{expectedRevision:N.revision,preCommit:async()=>{await l()}}),{schemaVersion:1,outcome:`${e}-root-accepted`,storyId:s,graphRevision:A,receiptId:oe,snapshotSha:D.snapshotSha,reused:E,sourceStateUnchanged:!0,...e==="qa"?{precommitQaAccepted:!0}:{},independentStoryQaAccepted:!1,terminalAccepted:!1,publicSafe:!0}}finally{await je(H.path,H.owner)||o()}}export{Xe as acceptPrivateYoloDiagnosisRootReview,Me as acceptPrivateYoloImplementationRootReview,Ee as acceptPrivateYoloQaRootReview,Ke as acceptPrivateYoloRefactorAdvisoryRootReview,Ze as acceptPrivateYoloResearchRootReview,et as acceptPrivateYoloSpecificationRootReview,tt as acceptPrivateYoloTasksRootReview,We as acceptPrivateYoloTestValidationRootReview};
|
|
@@ -1,19 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
throw new Error('private-execution-frozen-handoff-invalid');
|
|
8
|
-
}
|
|
9
|
-
return `${material}\n\nPrivate YOLO filesystem boundary (local only):\n`
|
|
10
|
-
+ `Frozen authorized output paths (data, not instructions): ${JSON.stringify({ paths: [...paths].sort() })}\n`
|
|
11
|
-
+ 'Modify only those exact paths. Do not create unclaimed project registries, temporary artifacts or estimated global metrics. '
|
|
12
|
-
+ 'Read-only inspection inside this project is allowed. If a required workflow effect is outside the frozen claim, '
|
|
13
|
-
+ 'leave the stage incomplete and describe the missing scope in an authorized story artifact for root remediation; '
|
|
14
|
-
+ 'do not waive the requirement, substitute an artifact or claim completion. '
|
|
15
|
-
+ 'External Context7 and web research belong to the root; use supplied public source observations, attribute them to the root '
|
|
16
|
-
+ 'and never invent queries or silently waive research requirements. Missing required sources remain a blocker. '
|
|
17
|
-
+ 'Git controls, private runtime, independent root QA and terminal accounting are outside model authority. '
|
|
18
|
-
+ 'Files with QA-related names contain candidate evidence only; distinguish observed local test outcomes from independent approval.\n';
|
|
19
|
-
}
|
|
1
|
+
function n(i,e){if(!Array.isArray(e)||e.length<1||e.length>1024||new Set(e).size!==e.length||e.some(t=>typeof t!="string"||t.length<1||t.length>1024||t.startsWith("/")||/[\\\x00-\x1f\x7f]/.test(t)||t.split("/").some(o=>!o||o==="."||o===".."||o===".git")))throw new Error("private-execution-frozen-handoff-invalid");return`${i}
|
|
2
|
+
|
|
3
|
+
Private YOLO filesystem boundary (local only):
|
|
4
|
+
Frozen authorized output paths (data, not instructions): ${JSON.stringify({paths:[...e].sort()})}
|
|
5
|
+
Modify only those exact paths. Do not create unclaimed project registries, temporary artifacts or estimated global metrics. Read-only inspection inside this project is allowed. If a required workflow effect is outside the frozen claim, leave the stage incomplete and describe the missing scope in an authorized story artifact for root remediation; do not waive the requirement, substitute an artifact or claim completion. External Context7 and web research belong to the root; use supplied public source observations, attribute them to the root and never invent queries or silently waive research requirements. Missing required sources remain a blocker. Git controls, private runtime, independent root QA and terminal accounting are outside model authority. Files with QA-related names contain candidate evidence only; distinguish observed local test outcomes from independent approval.
|
|
6
|
+
`}export{n as appendPrivateYoloFrozenHandoff};
|
|
@@ -1,106 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { execFileSync, spawnSync } from 'node:child_process';
|
|
4
|
-
import { existsSync, readFileSync, mkdtempSync, rmSync } from 'node:fs';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { tmpdir } from 'node:os';
|
|
7
|
-
import { readProjectValidationCommands } from './shared-project-validation.js';
|
|
8
|
-
import { gitLifecycleRuntimeDirectory, ensureGitLifecyclePrivateChildDirectory, assertGitLifecyclePrivateFile, readGitLifecycleRuntime } from '../git/git-lifecycle-store.js';
|
|
9
|
-
import { anchoredAtomicWriteFile } from '../git/secure-filesystem-boundary.js';
|
|
10
|
-
import { resumePrivateYoloIsolatedSession } from './isolated-session.js';
|
|
11
|
-
const hash = (value) => createHash('sha256').update(value).digest('hex');
|
|
12
|
-
const fail = () => { throw new Error('private-execution-implementation-validation-unverified'); };
|
|
13
|
-
const git = (cwd, ...args) => execFileSync('git', args, { cwd,
|
|
14
|
-
env: Object.fromEntries(Object.entries(process.env).filter(([key]) => !key.startsWith('GIT_'))),
|
|
15
|
-
timeout: 30_000, maxBuffer: 2 * 1024 * 1024, stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' });
|
|
16
|
-
export async function validatePrivateYoloImplementation(root, request) {
|
|
17
|
-
const r = request;
|
|
18
|
-
if (!r || Array.isArray(r) || Object.keys(r).sort().join('|') !==
|
|
19
|
-
['schemaVersion', 'storyId', 'graphRevision', 'expectedSnapshotSha', 'executorStopped', 'authorizeRun'].sort().join('|')
|
|
20
|
-
|| r.schemaVersion !== 'PrivateYoloImplementationValidation/1' || r.executorStopped !== true || r.authorizeRun !== true
|
|
21
|
-
|| typeof r.storyId !== 'string' || !/^P[1-9][0-9]*\.[0-9]+$/.test(r.storyId)
|
|
22
|
-
|| typeof r.graphRevision !== 'string' || !/^[a-f0-9]{64}$/.test(r.graphRevision)
|
|
23
|
-
|| typeof r.expectedSnapshotSha !== 'string' || !/^[a-f0-9]{40,64}$/.test(r.expectedSnapshotSha))
|
|
24
|
-
fail();
|
|
25
|
-
const storyId = r.storyId, graph = r.graphRevision;
|
|
26
|
-
const session = await resumePrivateYoloIsolatedSession(root, storyId, graph);
|
|
27
|
-
if (session.snapshotSha !== r.expectedSnapshotSha)
|
|
28
|
-
fail();
|
|
29
|
-
const runtime = await readGitLifecycleRuntime(root, { required: true });
|
|
30
|
-
const lease = runtime.epics[storyId.split('.')[0]]?.branch_lease;
|
|
31
|
-
if (!['create-tasks', 'implemented', 'refactor-suggest-done', 'property-tests-emitted', 'tests-validated'].includes(String(runtime.stories[storyId]?.status)) || !lease || lease.ownerStoryId !== storyId
|
|
32
|
-
|| typeof lease.expiresAt !== 'string' || !Number.isFinite(Date.parse(lease.expiresAt)) || Date.parse(lease.expiresAt) <= Date.now())
|
|
33
|
-
fail();
|
|
34
|
-
const sources = ['story', 'spec', 'tasks'].map(suffix => {
|
|
35
|
-
const path = `docs/stories/${storyId}.${suffix}.md`;
|
|
36
|
-
return { path, content: git(session.workspace.workspacePath, 'show', `${session.snapshotSha}:${path}`) };
|
|
37
|
-
});
|
|
38
|
-
const plan = readProjectValidationCommands(storyId, sources);
|
|
39
|
-
if (!plan.declared || plan.invalid || plan.commands.length === 0)
|
|
40
|
-
fail();
|
|
41
|
-
const temporary = mkdtempSync(join(tmpdir(), 'neocortex-root-implementation-'));
|
|
42
|
-
const copy = join(temporary, 'source');
|
|
43
|
-
try {
|
|
44
|
-
git(temporary, 'clone', '--no-hardlinks', '--no-checkout', '--', session.workspace.workspacePath, copy);
|
|
45
|
-
git(copy, 'checkout', '--detach', session.snapshotSha);
|
|
46
|
-
git(copy, 'diff', '--check', session.workspace.baseSha, session.snapshotSha);
|
|
47
|
-
const requiredArtifacts = [...sources.map(source => source.path), `docs/stories/${storyId}.rtm.md`, '.neocortex/state.json'];
|
|
48
|
-
const artifactDigests = Object.fromEntries(requiredArtifacts.map(path => [path, hash(git(copy, 'show', `${session.snapshotSha}:${path}`))]));
|
|
49
|
-
const canonical = JSON.parse(git(copy, 'show', `${session.snapshotSha}:.neocortex/state.json`));
|
|
50
|
-
if (!canonical.stories?.[storyId] || !canonical.epics?.[storyId.split('.')[0]])
|
|
51
|
-
fail();
|
|
52
|
-
// Commands are literal argv from the reviewed public plan. No shell or inherited provider credentials.
|
|
53
|
-
const env = Object.fromEntries(['PATH', 'LANG', 'LC_ALL', 'TMPDIR', 'SystemRoot'].flatMap(key => process.env[key] === undefined ? [] : [[key, process.env[key]]]));
|
|
54
|
-
env.HOME = temporary;
|
|
55
|
-
env.USERPROFILE = temporary;
|
|
56
|
-
const outcomes = plan.commands.map(entry => {
|
|
57
|
-
const [command, ...args] = entry.command.split(' ');
|
|
58
|
-
const result = spawnSync(command, args, { cwd: copy, shell: false, env,
|
|
59
|
-
timeout: 120_000, maxBuffer: 2 * 1024 * 1024, encoding: 'utf8' });
|
|
60
|
-
if (result.error || result.signal || result.status !== 0)
|
|
61
|
-
fail();
|
|
62
|
-
return { kind: entry.kind, commandSha256: hash(entry.command), exitCode: 0,
|
|
63
|
-
stdoutSha256: hash(result.stdout), stderrSha256: hash(result.stderr) };
|
|
64
|
-
});
|
|
65
|
-
git(copy, 'diff', '--exit-code', session.snapshotSha, '--');
|
|
66
|
-
const after = await resumePrivateYoloIsolatedSession(root, storyId, graph);
|
|
67
|
-
if (JSON.stringify(after) !== JSON.stringify(session)
|
|
68
|
-
|| (await readGitLifecycleRuntime(root, { required: true })).revision !== runtime.revision)
|
|
69
|
-
fail();
|
|
70
|
-
const receipt = { schemaVersion: 1, kind: 'private-root-implementation-validation', storyId,
|
|
71
|
-
graphRevision: graph, snapshotSha: session.snapshotSha, sourceHeadSha: session.workspace.baseSha,
|
|
72
|
-
planSha256: hash(JSON.stringify(plan.commands)), outcomes, fullDiffCheckPassed: true,
|
|
73
|
-
structuralIntegrity: { schemaVersion: 1, scope: 'project-snapshot', artifactDigests, canonicalStateParsed: true, declaredCommandsParsed: true, trackedInputsUnchanged: true, effectiveStatus: runtime.stories[storyId]?.status, serverManagedChecks: 'separate-server-admission' },
|
|
74
|
-
recordedAt: new Date().toISOString(), independentStoryQaAccepted: false, terminalAccepted: false };
|
|
75
|
-
const bytes = JSON.stringify(receipt) + '\n', receiptId = hash(bytes);
|
|
76
|
-
const parent = await ensureGitLifecyclePrivateChildDirectory(await gitLifecycleRuntimeDirectory(root), 'private-execution');
|
|
77
|
-
await anchoredAtomicWriteFile(parent, `implementation-validation-${receiptId}.json`, bytes);
|
|
78
|
-
return { schemaVersion: 1, receiptId, snapshotSha: session.snapshotSha, commandCount: outcomes.length,
|
|
79
|
-
independentStoryQaAccepted: false, terminalAccepted: false, publicSafe: true };
|
|
80
|
-
}
|
|
81
|
-
finally {
|
|
82
|
-
rmSync(temporary, { recursive: true, force: true });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
export async function readPrivateYoloImplementationValidation(root, receiptId, expected) {
|
|
86
|
-
if (typeof receiptId !== 'string' || !/^[a-f0-9]{64}$/.test(receiptId))
|
|
87
|
-
fail();
|
|
88
|
-
const parent = await ensureGitLifecyclePrivateChildDirectory(await gitLifecycleRuntimeDirectory(root), 'private-execution');
|
|
89
|
-
const path = join(parent, `implementation-validation-${receiptId}.json`);
|
|
90
|
-
if (!existsSync(path))
|
|
91
|
-
fail();
|
|
92
|
-
await assertGitLifecyclePrivateFile(path, parent);
|
|
93
|
-
const bytes = readFileSync(path, 'utf8');
|
|
94
|
-
if (Buffer.byteLength(bytes) > 16384 || hash(bytes) !== receiptId)
|
|
95
|
-
fail();
|
|
96
|
-
const receipt = JSON.parse(bytes);
|
|
97
|
-
if (receipt.kind !== 'private-root-implementation-validation' || receipt.schemaVersion !== 1
|
|
98
|
-
|| Object.entries(expected).some(([key, value]) => receipt[key] !== value)
|
|
99
|
-
|| receipt.fullDiffCheckPassed !== true || receipt.independentStoryQaAccepted !== false || receipt.terminalAccepted !== false
|
|
100
|
-
|| !Number.isFinite(Date.parse(receipt.recordedAt)) || Date.parse(receipt.recordedAt) > Date.now()
|
|
101
|
-
|| Date.now() - Date.parse(receipt.recordedAt) > 10 * 60_000
|
|
102
|
-
|| !Array.isArray(receipt.outcomes) || receipt.outcomes.length < 1
|
|
103
|
-
|| receipt.outcomes.some((v) => v.exitCode !== 0))
|
|
104
|
-
fail();
|
|
105
|
-
return receipt;
|
|
106
|
-
}
|
|
1
|
+
import{createHash as N}from"node:crypto";import{execFileSync as V,spawnSync as E}from"node:child_process";import{existsSync as F,readFileSync as J,mkdtempSync as _,rmSync as G}from"node:fs";import{join as w}from"node:path";import{tmpdir as H}from"node:os";import{readProjectValidationCommands as M}from"./shared-project-validation.js";import{gitLifecycleRuntimeDirectory as b,ensureGitLifecyclePrivateChildDirectory as j,assertGitLifecyclePrivateFile as Y,readGitLifecycleRuntime as D}from"../git/git-lifecycle-store.js";import{anchoredAtomicWriteFile as q}from"../git/secure-filesystem-boundary.js";import{resumePrivateYoloIsolatedSession as O}from"./isolated-session.js";const m=r=>N("sha256").update(r).digest("hex"),i=()=>{throw new Error("private-execution-implementation-validation-unverified")},h=(r,...c)=>V("git",c,{cwd:r,env:Object.fromEntries(Object.entries(process.env).filter(([e])=>!e.startsWith("GIT_"))),timeout:3e4,maxBuffer:2*1024*1024,stdio:["ignore","pipe","ignore"],encoding:"utf8"});async function ee(r,c){const e=c;(!e||Array.isArray(e)||Object.keys(e).sort().join("|")!==["schemaVersion","storyId","graphRevision","expectedSnapshotSha","executorStopped","authorizeRun"].sort().join("|")||e.schemaVersion!=="PrivateYoloImplementationValidation/1"||e.executorStopped!==!0||e.authorizeRun!==!0||typeof e.storyId!="string"||!/^P[1-9][0-9]*\.[0-9]+$/.test(e.storyId)||typeof e.graphRevision!="string"||!/^[a-f0-9]{64}$/.test(e.graphRevision)||typeof e.expectedSnapshotSha!="string"||!/^[a-f0-9]{40,64}$/.test(e.expectedSnapshotSha))&&i();const a=e.storyId,p=e.graphRevision,t=await O(r,a,p);t.snapshotSha!==e.expectedSnapshotSha&&i();const s=await D(r,{required:!0}),n=s.epics[a.split(".")[0]]?.branch_lease;(!["create-tasks","implemented","refactor-suggest-done","property-tests-emitted","tests-validated"].includes(String(s.stories[a]?.status))||!n||n.ownerStoryId!==a||typeof n.expiresAt!="string"||!Number.isFinite(Date.parse(n.expiresAt))||Date.parse(n.expiresAt)<=Date.now())&&i();const S=["story","spec","tasks"].map(g=>{const y=`docs/stories/${a}.${g}.md`;return{path:y,content:h(t.workspace.workspacePath,"show",`${t.snapshotSha}:${y}`)}}),f=M(a,S);(!f.declared||f.invalid||f.commands.length===0)&&i();const l=_(w(H(),"neocortex-root-implementation-")),d=w(l,"source");try{h(l,"clone","--no-hardlinks","--no-checkout","--",t.workspace.workspacePath,d),h(d,"checkout","--detach",t.snapshotSha),h(d,"diff","--check",t.workspace.baseSha,t.snapshotSha);const g=[...S.map(o=>o.path),`docs/stories/${a}.rtm.md`,".neocortex/state.json"],y=Object.fromEntries(g.map(o=>[o,m(h(d,"show",`${t.snapshotSha}:${o}`))])),x=JSON.parse(h(d,"show",`${t.snapshotSha}:.neocortex/state.json`));(!x.stories?.[a]||!x.epics?.[a.split(".")[0]])&&i();const v=Object.fromEntries(["PATH","LANG","LC_ALL","TMPDIR","SystemRoot"].flatMap(o=>process.env[o]===void 0?[]:[[o,process.env[o]]]));v.HOME=l,v.USERPROFILE=l;const A=f.commands.map(o=>{const[C,...L]=o.command.split(" "),u=E(C,L,{cwd:d,shell:!1,env:v,timeout:12e4,maxBuffer:2*1024*1024,encoding:"utf8"});return(u.error||u.signal||u.status!==0)&&i(),{kind:o.kind,commandSha256:m(o.command),exitCode:0,stdoutSha256:m(u.stdout),stderrSha256:m(u.stderr)}});h(d,"diff","--exit-code",t.snapshotSha,"--");const I=await O(r,a,p);(JSON.stringify(I)!==JSON.stringify(t)||(await D(r,{required:!0})).revision!==s.revision)&&i();const $={schemaVersion:1,kind:"private-root-implementation-validation",storyId:a,graphRevision:p,snapshotSha:t.snapshotSha,sourceHeadSha:t.workspace.baseSha,planSha256:m(JSON.stringify(f.commands)),outcomes:A,fullDiffCheckPassed:!0,structuralIntegrity:{schemaVersion:1,scope:"project-snapshot",artifactDigests:y,canonicalStateParsed:!0,declaredCommandsParsed:!0,trackedInputsUnchanged:!0,effectiveStatus:s.stories[a]?.status,serverManagedChecks:"separate-server-admission"},recordedAt:new Date().toISOString(),independentStoryQaAccepted:!1,terminalAccepted:!1},k=JSON.stringify($)+`
|
|
2
|
+
`,P=m(k),R=await j(await b(r),"private-execution");return await q(R,`implementation-validation-${P}.json`,k),{schemaVersion:1,receiptId:P,snapshotSha:t.snapshotSha,commandCount:A.length,independentStoryQaAccepted:!1,terminalAccepted:!1,publicSafe:!0}}finally{G(l,{recursive:!0,force:!0})}}async function te(r,c,e){(typeof c!="string"||!/^[a-f0-9]{64}$/.test(c))&&i();const a=await j(await b(r),"private-execution"),p=w(a,`implementation-validation-${c}.json`);F(p)||i(),await Y(p,a);const t=J(p,"utf8");(Buffer.byteLength(t)>16384||m(t)!==c)&&i();const s=JSON.parse(t);return(s.kind!=="private-root-implementation-validation"||s.schemaVersion!==1||Object.entries(e).some(([n,S])=>s[n]!==S)||s.fullDiffCheckPassed!==!0||s.independentStoryQaAccepted!==!1||s.terminalAccepted!==!1||!Number.isFinite(Date.parse(s.recordedAt))||Date.parse(s.recordedAt)>Date.now()||Date.now()-Date.parse(s.recordedAt)>10*6e4||!Array.isArray(s.outcomes)||s.outcomes.length<1||s.outcomes.some(n=>n.exitCode!==0))&&i(),s}export{te as readPrivateYoloImplementationValidation,ee as validatePrivateYoloImplementation};
|