@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
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export declare const EXPLICIT_INTENT_RECOVERY_VERSION: 1;
|
|
2
|
+
export type ExplicitIntentRecoveryReasonV1 = 'exact-admission-accepted' | 'recovery-positional-overflow-eligible' | 'recovery-not-positional-overflow' | 'recovery-command-not-exact-first' | 'recovery-command-schema-ineligible' | 'recovery-unsafe-token' | 'recovery-multiple-explicit-commands' | 'recovery-target-not-unique' | 'recovery-canonical-admission-conflict';
|
|
3
|
+
export interface ExplicitIntentRecoveryBindingV1 {
|
|
4
|
+
readonly schemaVersion: typeof EXPLICIT_INTENT_RECOVERY_VERSION;
|
|
5
|
+
readonly originalSha256: string;
|
|
6
|
+
readonly originalByteLength: number;
|
|
7
|
+
readonly canonicalSha256: string;
|
|
8
|
+
readonly canonicalByteLength: number;
|
|
9
|
+
readonly commandId: string;
|
|
10
|
+
readonly targetKind: 'story-ref' | 'epic-ref' | 'target-ref';
|
|
11
|
+
readonly discardedTokenCount: number;
|
|
12
|
+
readonly receiptSha256: string;
|
|
13
|
+
readonly reasonCode: 'recovery-positional-overflow-eligible';
|
|
14
|
+
readonly publicSafe: true;
|
|
15
|
+
}
|
|
16
|
+
export type ExplicitIntentRecoveryResultV1 = {
|
|
17
|
+
readonly schemaVersion: typeof EXPLICIT_INTENT_RECOVERY_VERSION;
|
|
18
|
+
readonly kind: 'exact';
|
|
19
|
+
readonly reasonCode: 'exact-admission-accepted';
|
|
20
|
+
readonly publicSafe: true;
|
|
21
|
+
} | {
|
|
22
|
+
readonly schemaVersion: typeof EXPLICIT_INTENT_RECOVERY_VERSION;
|
|
23
|
+
readonly kind: 'canonicalized';
|
|
24
|
+
readonly canonicalArgs: string;
|
|
25
|
+
readonly binding: ExplicitIntentRecoveryBindingV1;
|
|
26
|
+
readonly publicSafe: true;
|
|
27
|
+
} | {
|
|
28
|
+
readonly schemaVersion: typeof EXPLICIT_INTENT_RECOVERY_VERSION;
|
|
29
|
+
readonly kind: 'confirmation-required' | 'rejected';
|
|
30
|
+
readonly reasonCode: Exclude<ExplicitIntentRecoveryReasonV1, 'exact-admission-accepted' | 'recovery-positional-overflow-eligible'>;
|
|
31
|
+
readonly candidateCount: number;
|
|
32
|
+
readonly publicSafe: true;
|
|
33
|
+
};
|
|
34
|
+
interface RecoveryAdmissionProjection {
|
|
35
|
+
readonly outcome: string;
|
|
36
|
+
readonly reason: string;
|
|
37
|
+
readonly selection?: {
|
|
38
|
+
readonly commandId: string;
|
|
39
|
+
readonly positionals: readonly string[];
|
|
40
|
+
readonly options: Readonly<Record<string, unknown>>;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
interface RecoveryTokenProjection {
|
|
44
|
+
readonly value: string;
|
|
45
|
+
readonly whollyUnquoted: boolean;
|
|
46
|
+
}
|
|
47
|
+
interface RecoveryCommandProjection {
|
|
48
|
+
readonly id: string;
|
|
49
|
+
readonly aliases: readonly string[];
|
|
50
|
+
readonly number: number;
|
|
51
|
+
}
|
|
52
|
+
interface RecoverySchemaProjection {
|
|
53
|
+
readonly commandId: string;
|
|
54
|
+
readonly operation: {
|
|
55
|
+
readonly operations: readonly unknown[];
|
|
56
|
+
};
|
|
57
|
+
readonly options: readonly {
|
|
58
|
+
readonly required: boolean;
|
|
59
|
+
}[];
|
|
60
|
+
readonly positionals: readonly {
|
|
61
|
+
readonly kind: string;
|
|
62
|
+
readonly cardinality: string;
|
|
63
|
+
readonly required: boolean;
|
|
64
|
+
}[];
|
|
65
|
+
}
|
|
66
|
+
export interface ExplicitIntentRecoveryAuthority {
|
|
67
|
+
readonly input: string;
|
|
68
|
+
readonly exactAdmission: RecoveryAdmissionProjection;
|
|
69
|
+
readonly tokens: readonly RecoveryTokenProjection[] | null;
|
|
70
|
+
readonly commands: readonly RecoveryCommandProjection[];
|
|
71
|
+
readonly schemas: readonly RecoverySchemaProjection[];
|
|
72
|
+
readonly admitCanonical: (candidate: string) => RecoveryAdmissionProjection;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* P224.02 exact-first recovery kernel.
|
|
76
|
+
*
|
|
77
|
+
* The caller supplies the exact parser, schema and lexer projections so this
|
|
78
|
+
* module stays pure and cannot become a second registry or parser. The result
|
|
79
|
+
* never contains discarded prose or the original input bytes.
|
|
80
|
+
*/
|
|
81
|
+
export declare function recoverExplicitIntentWithAuthority(authority: ExplicitIntentRecoveryAuthority): ExplicitIntentRecoveryResultV1;
|
|
82
|
+
export declare function assertExplicitIntentRecoveryBindingV1(value: unknown, canonicalArgs?: string): asserts value is ExplicitIntentRecoveryBindingV1;
|
|
83
|
+
export {};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export const EXPLICIT_INTENT_RECOVERY_VERSION = 1;
|
|
3
|
+
function sha256(value) {
|
|
4
|
+
return createHash('sha256').update(value, 'utf8').digest('hex');
|
|
5
|
+
}
|
|
6
|
+
function rejected(kind, reasonCode, candidateCount = 0) {
|
|
7
|
+
return Object.freeze({
|
|
8
|
+
schemaVersion: EXPLICIT_INTENT_RECOVERY_VERSION,
|
|
9
|
+
kind,
|
|
10
|
+
reasonCode,
|
|
11
|
+
candidateCount: Math.max(0, Math.min(candidateCount, 16)),
|
|
12
|
+
publicSafe: true,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function commandForFirstToken(token, commands) {
|
|
16
|
+
if (!token.whollyUnquoted)
|
|
17
|
+
return undefined;
|
|
18
|
+
const normalized = token.value.replace(/^\*/, '').toLowerCase();
|
|
19
|
+
if (!token.value.startsWith('*') || !/^[a-z][a-z0-9?-]*$/.test(normalized))
|
|
20
|
+
return undefined;
|
|
21
|
+
return commands.find((command) => command.id === normalized || command.aliases.includes(normalized));
|
|
22
|
+
}
|
|
23
|
+
function isExplicitCommandToken(token, commands) {
|
|
24
|
+
if (!token.whollyUnquoted || !token.value.startsWith('*'))
|
|
25
|
+
return false;
|
|
26
|
+
const normalized = token.value.slice(1).toLowerCase();
|
|
27
|
+
return commands.some((command) => command.id === normalized || command.aliases.includes(normalized));
|
|
28
|
+
}
|
|
29
|
+
function recoverableTypedTarget(kind, value) {
|
|
30
|
+
const candidate = value.startsWith('@') ? value.slice(1) : value;
|
|
31
|
+
if (kind === 'story-ref') {
|
|
32
|
+
return /^(?:docs\/stories\/[A-Za-z0-9._/-]+\.story\.md|P\d+\.\d+|story-P\d+\.\d+)$/.test(candidate);
|
|
33
|
+
}
|
|
34
|
+
if (kind === 'epic-ref') {
|
|
35
|
+
return /^(?:docs\/epics\/epic-[A-Za-z0-9][A-Za-z0-9_-]*\.md|P\d+|epic-[A-Za-z0-9][A-Za-z0-9_-]*(?:\.md)?)$/i.test(candidate);
|
|
36
|
+
}
|
|
37
|
+
return /^(?:P\d+|EPIC-\d+)$/i.test(candidate)
|
|
38
|
+
|| /^docs\/epics\/?$/.test(candidate)
|
|
39
|
+
|| /^docs\/epics\/epic-[A-Za-z0-9][A-Za-z0-9_-]*\.md$/i.test(candidate);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* P224.02 exact-first recovery kernel.
|
|
43
|
+
*
|
|
44
|
+
* The caller supplies the exact parser, schema and lexer projections so this
|
|
45
|
+
* module stays pure and cannot become a second registry or parser. The result
|
|
46
|
+
* never contains discarded prose or the original input bytes.
|
|
47
|
+
*/
|
|
48
|
+
export function recoverExplicitIntentWithAuthority(authority) {
|
|
49
|
+
if (authority.exactAdmission.outcome === 'resolved') {
|
|
50
|
+
return Object.freeze({
|
|
51
|
+
schemaVersion: EXPLICIT_INTENT_RECOVERY_VERSION,
|
|
52
|
+
kind: 'exact',
|
|
53
|
+
reasonCode: 'exact-admission-accepted',
|
|
54
|
+
publicSafe: true,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (authority.exactAdmission.outcome !== 'invalid_arguments'
|
|
58
|
+
|| authority.exactAdmission.reason !== 'positional_overflow') {
|
|
59
|
+
return rejected('rejected', 'recovery-not-positional-overflow');
|
|
60
|
+
}
|
|
61
|
+
const tokens = authority.tokens;
|
|
62
|
+
if (!tokens || tokens.length < 3) {
|
|
63
|
+
return rejected('rejected', 'recovery-command-not-exact-first');
|
|
64
|
+
}
|
|
65
|
+
const command = commandForFirstToken(tokens[0], authority.commands);
|
|
66
|
+
if (!command)
|
|
67
|
+
return rejected('rejected', 'recovery-command-not-exact-first');
|
|
68
|
+
const schema = authority.schemas.find((item) => item.commandId === command.id);
|
|
69
|
+
const positional = schema?.positionals[0];
|
|
70
|
+
if (!schema
|
|
71
|
+
|| schema.operation.operations.length > 0
|
|
72
|
+
|| schema.options.some((option) => option.required)
|
|
73
|
+
|| schema.positionals.length !== 1
|
|
74
|
+
|| positional?.cardinality !== 'one'
|
|
75
|
+
|| !['story-ref', 'epic-ref', 'target-ref'].includes(positional.kind)) {
|
|
76
|
+
return rejected('rejected', 'recovery-command-schema-ineligible');
|
|
77
|
+
}
|
|
78
|
+
if (tokens.slice(1).some((token) => isExplicitCommandToken(token, authority.commands))) {
|
|
79
|
+
return rejected('confirmation-required', 'recovery-multiple-explicit-commands');
|
|
80
|
+
}
|
|
81
|
+
// Recovery never discards quoted material or option-shaped tokens. Exact
|
|
82
|
+
// admission remains responsible for accepted options and quoted arguments.
|
|
83
|
+
if (tokens.slice(1).some((token) => !token.whollyUnquoted || token.value.startsWith('--')
|
|
84
|
+
|| token.value.startsWith('*'))) {
|
|
85
|
+
return rejected('confirmation-required', 'recovery-unsafe-token');
|
|
86
|
+
}
|
|
87
|
+
const candidates = tokens.slice(1).flatMap((token) => {
|
|
88
|
+
if (!recoverableTypedTarget(positional.kind, token.value)) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
const canonicalArgs = `*${command.id} ${token.value}`;
|
|
92
|
+
const admission = authority.admitCanonical(canonicalArgs);
|
|
93
|
+
if (admission.outcome !== 'resolved'
|
|
94
|
+
|| admission.selection?.commandId !== command.id
|
|
95
|
+
|| admission.selection.positionals.length !== 1
|
|
96
|
+
|| Object.keys(admission.selection.options).length !== 0)
|
|
97
|
+
return [];
|
|
98
|
+
return [{ canonicalArgs, target: admission.selection.positionals[0] }];
|
|
99
|
+
});
|
|
100
|
+
const unique = [...new Map(candidates.map((candidate) => [candidate.canonicalArgs, candidate])).values()];
|
|
101
|
+
if (unique.length !== 1) {
|
|
102
|
+
return rejected('confirmation-required', 'recovery-target-not-unique', unique.length);
|
|
103
|
+
}
|
|
104
|
+
const selected = unique[0];
|
|
105
|
+
const finalAdmission = authority.admitCanonical(selected.canonicalArgs);
|
|
106
|
+
if (finalAdmission.outcome !== 'resolved'
|
|
107
|
+
|| finalAdmission.selection?.commandId !== command.id
|
|
108
|
+
|| finalAdmission.selection.positionals[0] !== selected.target) {
|
|
109
|
+
return rejected('rejected', 'recovery-canonical-admission-conflict', 1);
|
|
110
|
+
}
|
|
111
|
+
const originalSha256 = sha256(authority.input);
|
|
112
|
+
const canonicalSha256 = sha256(selected.canonicalArgs);
|
|
113
|
+
const base = {
|
|
114
|
+
schemaVersion: EXPLICIT_INTENT_RECOVERY_VERSION,
|
|
115
|
+
originalSha256,
|
|
116
|
+
originalByteLength: Buffer.byteLength(authority.input, 'utf8'),
|
|
117
|
+
canonicalSha256,
|
|
118
|
+
canonicalByteLength: Buffer.byteLength(selected.canonicalArgs, 'utf8'),
|
|
119
|
+
commandId: command.id,
|
|
120
|
+
targetKind: positional.kind,
|
|
121
|
+
discardedTokenCount: tokens.length - 2,
|
|
122
|
+
reasonCode: 'recovery-positional-overflow-eligible',
|
|
123
|
+
publicSafe: true,
|
|
124
|
+
};
|
|
125
|
+
const receiptSha256 = sha256(`p224-explicit-intent-recovery-v1\0${JSON.stringify(base)}`);
|
|
126
|
+
return Object.freeze({
|
|
127
|
+
schemaVersion: EXPLICIT_INTENT_RECOVERY_VERSION,
|
|
128
|
+
kind: 'canonicalized',
|
|
129
|
+
canonicalArgs: selected.canonicalArgs,
|
|
130
|
+
binding: Object.freeze({ ...base, receiptSha256 }),
|
|
131
|
+
publicSafe: true,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
export function assertExplicitIntentRecoveryBindingV1(value, canonicalArgs) {
|
|
135
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
136
|
+
throw new Error('EXPLICIT_INTENT_RECOVERY_BINDING_INVALID');
|
|
137
|
+
}
|
|
138
|
+
const candidate = value;
|
|
139
|
+
const expectedKeys = [
|
|
140
|
+
'canonicalByteLength', 'canonicalSha256', 'commandId', 'discardedTokenCount',
|
|
141
|
+
'originalByteLength', 'originalSha256', 'publicSafe', 'reasonCode',
|
|
142
|
+
'receiptSha256', 'schemaVersion', 'targetKind',
|
|
143
|
+
];
|
|
144
|
+
if (Object.keys(candidate).sort().join('\0') !== expectedKeys.sort().join('\0')
|
|
145
|
+
|| candidate.schemaVersion !== EXPLICIT_INTENT_RECOVERY_VERSION
|
|
146
|
+
|| !['story-ref', 'epic-ref', 'target-ref'].includes(String(candidate.targetKind))
|
|
147
|
+
|| typeof candidate.commandId !== 'string'
|
|
148
|
+
|| !/^[a-z][a-z0-9?-]{0,63}$/.test(candidate.commandId)
|
|
149
|
+
|| typeof candidate.originalSha256 !== 'string'
|
|
150
|
+
|| !/^[a-f0-9]{64}$/.test(candidate.originalSha256)
|
|
151
|
+
|| typeof candidate.canonicalSha256 !== 'string'
|
|
152
|
+
|| !/^[a-f0-9]{64}$/.test(candidate.canonicalSha256)
|
|
153
|
+
|| typeof candidate.receiptSha256 !== 'string'
|
|
154
|
+
|| !/^[a-f0-9]{64}$/.test(candidate.receiptSha256)
|
|
155
|
+
|| !Number.isSafeInteger(candidate.originalByteLength)
|
|
156
|
+
|| candidate.originalByteLength < 1
|
|
157
|
+
|| !Number.isSafeInteger(candidate.canonicalByteLength)
|
|
158
|
+
|| candidate.canonicalByteLength < 1
|
|
159
|
+
|| !Number.isSafeInteger(candidate.discardedTokenCount)
|
|
160
|
+
|| candidate.discardedTokenCount < 1
|
|
161
|
+
|| candidate.discardedTokenCount > 512
|
|
162
|
+
|| candidate.reasonCode !== 'recovery-positional-overflow-eligible'
|
|
163
|
+
|| candidate.publicSafe !== true) {
|
|
164
|
+
throw new Error('EXPLICIT_INTENT_RECOVERY_BINDING_INVALID');
|
|
165
|
+
}
|
|
166
|
+
if (canonicalArgs !== undefined
|
|
167
|
+
&& (candidate.canonicalByteLength !== Buffer.byteLength(canonicalArgs, 'utf8')
|
|
168
|
+
|| candidate.canonicalSha256 !== sha256(canonicalArgs))) {
|
|
169
|
+
throw new Error('EXPLICIT_INTENT_RECOVERY_BINDING_CONFLICT');
|
|
170
|
+
}
|
|
171
|
+
const receiptBase = {
|
|
172
|
+
schemaVersion: candidate.schemaVersion,
|
|
173
|
+
originalSha256: candidate.originalSha256,
|
|
174
|
+
originalByteLength: candidate.originalByteLength,
|
|
175
|
+
canonicalSha256: candidate.canonicalSha256,
|
|
176
|
+
canonicalByteLength: candidate.canonicalByteLength,
|
|
177
|
+
commandId: candidate.commandId,
|
|
178
|
+
targetKind: candidate.targetKind,
|
|
179
|
+
discardedTokenCount: candidate.discardedTokenCount,
|
|
180
|
+
reasonCode: candidate.reasonCode,
|
|
181
|
+
publicSafe: candidate.publicSafe,
|
|
182
|
+
};
|
|
183
|
+
if (candidate.receiptSha256
|
|
184
|
+
!== sha256(`p224-explicit-intent-recovery-v1\0${JSON.stringify(receiptBase)}`)) {
|
|
185
|
+
throw new Error('EXPLICIT_INTENT_RECOVERY_BINDING_CONFLICT');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ExplicitIntentRecoveryResultV1 } from './explicit-intent-recovery.js';
|
|
1
2
|
export * from './input-envelope.js';
|
|
2
3
|
export * from './project-identity-migration.js';
|
|
3
4
|
export * from './state-projection.js';
|
|
@@ -5,6 +6,7 @@ export * from './strict-effect-receipt.js';
|
|
|
5
6
|
export * from './public-diagnostics.js';
|
|
6
7
|
export * from './recovery-route-compiler.js';
|
|
7
8
|
export * from './executable-policy-recovery.js';
|
|
9
|
+
export * from './explicit-intent-recovery.js';
|
|
8
10
|
export declare const EXACT_INVOCATION_POLICY: "p205-exact-invocation-v1";
|
|
9
11
|
export declare const INVOCATION_SCHEMA_VERSION: "p205-invocation-schema-v1";
|
|
10
12
|
export declare const INVOCATION_LIMITS: Readonly<{
|
|
@@ -147,6 +149,11 @@ type LexResult = {
|
|
|
147
149
|
};
|
|
148
150
|
export declare function lexInvocationEnvelope(input: string): LexResult;
|
|
149
151
|
export declare function admitInvocation(input: string, options?: InvocationAdmissionOptions): InvocationAdmissionResultV1;
|
|
152
|
+
/**
|
|
153
|
+
* P224.02 public exact-first recovery facade. It reuses this module's single
|
|
154
|
+
* registry, schema, lexer and admission authority instead of duplicating policy.
|
|
155
|
+
*/
|
|
156
|
+
export declare function recoverExplicitInvocation(input: string, options?: InvocationAdmissionOptions): ExplicitIntentRecoveryResultV1;
|
|
150
157
|
export interface InvocationAdmissionReceiptV1 {
|
|
151
158
|
readonly schemaVersion: 1;
|
|
152
159
|
readonly policy: typeof EXACT_INVOCATION_POLICY;
|
|
@@ -10,6 +10,7 @@ import { COMMAND_REGISTRY_CHECKSUM, COMMAND_REGISTRY_VERSION, GENERATED_SHARED_C
|
|
|
10
10
|
import { GENERATED_INVOCATION_SCHEMA_MANIFEST, GENERATED_INVOCATION_SCHEMAS, } from '../generated/invocation-schema.generated.js';
|
|
11
11
|
import { canonicalizeCommandRegistryJcs } from '../command-registry-contract.js';
|
|
12
12
|
import { CONTINUITY_GOAL_OPERATION_IDS } from '../continuity/goal-operation-authority.js';
|
|
13
|
+
import { recoverExplicitIntentWithAuthority, } from './explicit-intent-recovery.js';
|
|
13
14
|
export * from './input-envelope.js';
|
|
14
15
|
export * from './project-identity-migration.js';
|
|
15
16
|
export * from './state-projection.js';
|
|
@@ -17,6 +18,7 @@ export * from './strict-effect-receipt.js';
|
|
|
17
18
|
export * from './public-diagnostics.js';
|
|
18
19
|
export * from './recovery-route-compiler.js';
|
|
19
20
|
export * from './executable-policy-recovery.js';
|
|
21
|
+
export * from './explicit-intent-recovery.js';
|
|
20
22
|
export const EXACT_INVOCATION_POLICY = 'p205-exact-invocation-v1';
|
|
21
23
|
export const INVOCATION_SCHEMA_VERSION = 'p205-invocation-schema-v1';
|
|
22
24
|
export const INVOCATION_LIMITS = Object.freeze({
|
|
@@ -598,6 +600,26 @@ export function admitInvocation(input, options = {}) {
|
|
|
598
600
|
return reject('invalid_arguments', uiUxReview, lexed.tokens.length, bytes);
|
|
599
601
|
return resolved(command, operation.operationId, parsed, uiUxReview, lexed.tokens.length, bytes);
|
|
600
602
|
}
|
|
603
|
+
/**
|
|
604
|
+
* P224.02 public exact-first recovery facade. It reuses this module's single
|
|
605
|
+
* registry, schema, lexer and admission authority instead of duplicating policy.
|
|
606
|
+
*/
|
|
607
|
+
export function recoverExplicitInvocation(input, options = {}) {
|
|
608
|
+
const exactAdmission = admitInvocation(input, options);
|
|
609
|
+
const lexed = lexInvocationEnvelope(input);
|
|
610
|
+
return recoverExplicitIntentWithAuthority({
|
|
611
|
+
input,
|
|
612
|
+
exactAdmission,
|
|
613
|
+
tokens: lexed.ok ? lexed.tokens : null,
|
|
614
|
+
commands: commands.map((command) => ({
|
|
615
|
+
id: command.id,
|
|
616
|
+
aliases: command.aliases,
|
|
617
|
+
number: command.number,
|
|
618
|
+
})),
|
|
619
|
+
schemas: invocationSchemas,
|
|
620
|
+
admitCanonical: (candidate) => admitInvocation(candidate, options),
|
|
621
|
+
});
|
|
622
|
+
}
|
|
601
623
|
function resolved(command, operationId, parsed, uiUxReview, tokenCount, bytes) {
|
|
602
624
|
const selection = freeze({
|
|
603
625
|
commandId: command.id,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { posix } from 'node:path';
|
|
3
3
|
const SHA = /^[a-f0-9]{40}(?:[a-f0-9]{24})?$/;
|
|
4
|
-
const PATH = /^[A-Za-z0-9_
|
|
4
|
+
const PATH = /^[A-Za-z0-9_.\[\]-][A-Za-z0-9_./ \[\]-]{0,239}$/;
|
|
5
5
|
const UNSAFE = /(^|\/)(?:\.env(?:\.|$)|secrets?|credentials?|private-prompts?|customer-data)(?:\/|$)|(?:token|password|license[_-]?key|secret)[=:]/i;
|
|
6
6
|
function digest(paths) {
|
|
7
7
|
return createHash('sha256').update(JSON.stringify(paths)).digest('hex');
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
/** Public contracts and pure safety decisions for epic-owned terminal Git. */
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
/**
|
|
4
|
+
* P205 complete-gate budgets are declared in config/release-gates.v2.json and
|
|
5
|
+
* mirrored here so installed clients keep the same closed runtime bounds.
|
|
6
|
+
* release-gates.test.mjs prevents either side from drifting independently.
|
|
7
|
+
*/
|
|
8
|
+
export const P205_RELEASE_GATE_BUDGETS = Object.freeze({
|
|
9
|
+
completeGateWorstCaseMs: 45 * 60 * 1000,
|
|
10
|
+
cancellationGraceMs: 5 * 60 * 1000,
|
|
11
|
+
aggregateValidityMs: 2 * 60 * 60 * 1000,
|
|
12
|
+
terminalWorkflowMaxDurationMs: 2 * 60 * 60 * 1000,
|
|
13
|
+
});
|
|
14
|
+
export const P205_ROOT_INVOKE_TIMEOUT_MS = P205_RELEASE_GATE_BUDGETS.completeGateWorstCaseMs + P205_RELEASE_GATE_BUDGETS.cancellationGraceMs;
|
|
2
15
|
export const EPIC_TERMINAL_GIT_REASON_CODES = Object.freeze({
|
|
3
16
|
READY: 'epic-terminal-git-ready',
|
|
4
17
|
ALREADY_COMPLETE: 'epic-terminal-git-already-complete',
|
|
@@ -38,6 +51,96 @@ export const EPIC_TERMINAL_GIT_REASON_CODES = Object.freeze({
|
|
|
38
51
|
PR_BASE_GUARD_UNVERIFIABLE: 'epic-terminal-pr-base-guard-unverifiable',
|
|
39
52
|
PR_MERGE_QUEUE_LOCAL_GATE_REQUIRED: 'epic-terminal-pr-merge-queue-local-gate-required',
|
|
40
53
|
});
|
|
54
|
+
export function epicHeadReconciliationRangeDigest(lastAcceptedCheckpointHeadSha, executionHeadSha, reconciliationCommitShas) {
|
|
55
|
+
return createHash('sha256').update([
|
|
56
|
+
'epic-head-reconciliation-range-v1',
|
|
57
|
+
lastAcceptedCheckpointHeadSha,
|
|
58
|
+
executionHeadSha,
|
|
59
|
+
...reconciliationCommitShas,
|
|
60
|
+
].join('\0')).digest('hex');
|
|
61
|
+
}
|
|
62
|
+
export function epicHeadReconciliationPathsDigest(paths) {
|
|
63
|
+
return createHash('sha256').update(paths.join('\0')).digest('hex');
|
|
64
|
+
}
|
|
65
|
+
export function epicHeadReconciliationInputDigest(value) {
|
|
66
|
+
return createHash('sha256').update(JSON.stringify({
|
|
67
|
+
schemaVersion: value.schemaVersion,
|
|
68
|
+
kind: value.kind,
|
|
69
|
+
producer: value.producer,
|
|
70
|
+
epicId: value.epicId,
|
|
71
|
+
executionBranch: value.executionBranch,
|
|
72
|
+
originBranch: value.originBranch,
|
|
73
|
+
graphRevision: value.graphRevision,
|
|
74
|
+
originHeadSha: value.originHeadSha,
|
|
75
|
+
lastAcceptedCheckpointHeadSha: value.lastAcceptedCheckpointHeadSha,
|
|
76
|
+
executionHeadSha: value.executionHeadSha,
|
|
77
|
+
acceptedCheckpointIds: value.acceptedCheckpointIds,
|
|
78
|
+
acceptedCheckpointHeads: value.acceptedCheckpointHeads,
|
|
79
|
+
reconciliationCommitShas: value.reconciliationCommitShas,
|
|
80
|
+
commitRangeDigest: value.commitRangeDigest,
|
|
81
|
+
changedPaths: value.changedPaths,
|
|
82
|
+
changedPathsDigest: value.changedPathsDigest,
|
|
83
|
+
allowedWriteSet: value.allowedWriteSet,
|
|
84
|
+
allowedWriteSetDigest: value.allowedWriteSetDigest,
|
|
85
|
+
aggregateReceiptRef: value.aggregateReceiptRef,
|
|
86
|
+
aggregateManifestDigest: value.aggregateManifestDigest,
|
|
87
|
+
aggregateResultDigest: value.aggregateResultDigest,
|
|
88
|
+
producedAt: value.producedAt,
|
|
89
|
+
revalidatedAt: value.revalidatedAt,
|
|
90
|
+
publicSafe: value.publicSafe,
|
|
91
|
+
})).digest('hex');
|
|
92
|
+
}
|
|
93
|
+
export function validateEpicHeadReconciliationReceipt(value, expected) {
|
|
94
|
+
if (!value || value.schemaVersion !== 1 || value.kind !== 'epic_head_reconciliation'
|
|
95
|
+
|| value.producer !== 'client-p205-head-reconciliation-v1' || value.publicSafe !== true
|
|
96
|
+
|| !nonEmpty(value.epicId) || !nonEmpty(value.executionBranch) || !nonEmpty(value.originBranch)
|
|
97
|
+
|| !Array.isArray(value.acceptedCheckpointIds) || !Array.isArray(value.acceptedCheckpointHeads)
|
|
98
|
+
|| !Array.isArray(value.reconciliationCommitShas) || !Array.isArray(value.changedPaths)
|
|
99
|
+
|| !Array.isArray(value.allowedWriteSet)
|
|
100
|
+
|| value.epicId !== expected.epicId || value.executionBranch !== expected.executionBranch
|
|
101
|
+
|| value.originBranch !== expected.originBranch || value.graphRevision !== expected.graphRevision
|
|
102
|
+
|| value.originHeadSha !== expected.originHeadSha || value.executionHeadSha !== expected.executionHeadSha
|
|
103
|
+
|| value.lastAcceptedCheckpointHeadSha !== expected.acceptedCheckpointHeads.at(-1)
|
|
104
|
+
|| !sameOrdered(value.acceptedCheckpointIds, expected.acceptedCheckpointIds)
|
|
105
|
+
|| !sameOrdered(value.acceptedCheckpointHeads, expected.acceptedCheckpointHeads)
|
|
106
|
+
|| value.aggregateReceiptRef !== expected.aggregateQaReceipt.receiptRef
|
|
107
|
+
|| value.aggregateManifestDigest !== expected.aggregateQaReceipt.manifestDigest
|
|
108
|
+
|| value.aggregateResultDigest !== expected.aggregateQaReceipt.resultDigest
|
|
109
|
+
|| !nonEmpty(value.aggregateReceiptRef) || !isHash(value.aggregateManifestDigest)
|
|
110
|
+
|| !isHash(value.aggregateResultDigest) || !nonEmpty(value.producedAt) || !nonEmpty(value.revalidatedAt)
|
|
111
|
+
|| value.acceptedCheckpointIds.length === 0 || value.acceptedCheckpointIds.length > 2_048
|
|
112
|
+
|| value.acceptedCheckpointIds.some((id) => !nonEmpty(id) || id.length > 240)
|
|
113
|
+
|| value.reconciliationCommitShas.length > 2_048
|
|
114
|
+
|| value.changedPaths.length > 2_048
|
|
115
|
+
|| value.allowedWriteSet.length === 0 || value.allowedWriteSet.length > 2_048
|
|
116
|
+
|| (value.lastAcceptedCheckpointHeadSha !== value.executionHeadSha
|
|
117
|
+
&& (value.reconciliationCommitShas.length === 0 || value.changedPaths.length === 0))
|
|
118
|
+
|| (value.lastAcceptedCheckpointHeadSha === value.executionHeadSha
|
|
119
|
+
&& (value.reconciliationCommitShas.length !== 0 || value.changedPaths.length !== 0))
|
|
120
|
+
|| !isFullSha(value.originHeadSha) || !isFullSha(value.lastAcceptedCheckpointHeadSha)
|
|
121
|
+
|| !isFullSha(value.executionHeadSha) || !isHash(value.graphRevision)
|
|
122
|
+
|| value.acceptedCheckpointHeads.some((sha) => !isFullSha(sha))
|
|
123
|
+
|| value.reconciliationCommitShas.some((sha) => !isFullSha(sha))
|
|
124
|
+
|| !sameOrdered(value.changedPaths, [...new Set(value.changedPaths)].sort())
|
|
125
|
+
|| !sameOrdered(value.allowedWriteSet, [...new Set(value.allowedWriteSet)].sort())
|
|
126
|
+
|| value.changedPaths.some((path) => !safeRepositoryPath(path))
|
|
127
|
+
|| value.allowedWriteSet.some((path) => !safeWriteScope(path))
|
|
128
|
+
|| value.changedPaths.some((path) => !value.allowedWriteSet.some((scope) => writeScopeCovers(scope, path)))
|
|
129
|
+
|| value.commitRangeDigest !== epicHeadReconciliationRangeDigest(value.lastAcceptedCheckpointHeadSha, value.executionHeadSha, value.reconciliationCommitShas)
|
|
130
|
+
|| value.changedPathsDigest !== epicHeadReconciliationPathsDigest(value.changedPaths)
|
|
131
|
+
|| value.allowedWriteSetDigest !== epicHeadReconciliationPathsDigest(value.allowedWriteSet)
|
|
132
|
+
|| value.inputDigest !== epicHeadReconciliationInputDigest(value)
|
|
133
|
+
|| !isHash(value.commitRangeDigest) || !isHash(value.changedPathsDigest)
|
|
134
|
+
|| !isHash(value.allowedWriteSetDigest) || !isHash(value.inputDigest))
|
|
135
|
+
return false;
|
|
136
|
+
const producedAt = Date.parse(value.producedAt);
|
|
137
|
+
const revalidatedAt = Date.parse(value.revalidatedAt);
|
|
138
|
+
const now = Date.parse(expected.nowIso);
|
|
139
|
+
return Number.isFinite(producedAt) && Number.isFinite(revalidatedAt) && Number.isFinite(now)
|
|
140
|
+
&& revalidatedAt >= producedAt
|
|
141
|
+
&& now - revalidatedAt <= P205_RELEASE_GATE_BUDGETS.aggregateValidityMs
|
|
142
|
+
&& revalidatedAt - now <= P205_RELEASE_GATE_BUDGETS.cancellationGraceMs;
|
|
143
|
+
}
|
|
41
144
|
export function validateEpicTerminalGitDirective(directive, actual) {
|
|
42
145
|
const reasons = [];
|
|
43
146
|
if (!nonEmpty(directive.originBranch))
|
|
@@ -76,8 +179,8 @@ export function validateEpicTerminalGitDirective(directive, actual) {
|
|
|
76
179
|
|| !directive.localGates.receiptRefs.includes(aggregate.receiptRef)) {
|
|
77
180
|
reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.AGGREGATE_QA_REQUIRED);
|
|
78
181
|
}
|
|
79
|
-
else if (!Number.isFinite(Date.parse(aggregate.checkedAt)) || actual.nowIso && (Date.parse(actual.nowIso) - Date.parse(aggregate.checkedAt) >
|
|
80
|
-
|| Date.parse(aggregate.checkedAt) - Date.parse(actual.nowIso) >
|
|
182
|
+
else if (!Number.isFinite(Date.parse(aggregate.checkedAt)) || actual.nowIso && (Date.parse(actual.nowIso) - Date.parse(aggregate.checkedAt) > P205_RELEASE_GATE_BUDGETS.aggregateValidityMs
|
|
183
|
+
|| Date.parse(aggregate.checkedAt) - Date.parse(actual.nowIso) > P205_RELEASE_GATE_BUDGETS.cancellationGraceMs)) {
|
|
81
184
|
reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.AGGREGATE_QA_STALE);
|
|
82
185
|
}
|
|
83
186
|
const originBinding = actual.originBinding;
|
|
@@ -90,6 +193,24 @@ export function validateEpicTerminalGitDirective(directive, actual) {
|
|
|
90
193
|
|| !Number.isFinite(Date.parse(originBinding.capturedAt))) {
|
|
91
194
|
reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.ORIGIN_BINDING_REQUIRED);
|
|
92
195
|
}
|
|
196
|
+
const directedReconciliation = directive.localGates?.headReconciliationReceipt;
|
|
197
|
+
const actualReconciliation = actual.headReconciliationReceipt;
|
|
198
|
+
if (directedReconciliation && (!actualReconciliation || !originBinding || !aggregate
|
|
199
|
+
|| directedReconciliation.inputDigest !== actualReconciliation.inputDigest
|
|
200
|
+
|| !validateEpicHeadReconciliationReceipt(actualReconciliation, {
|
|
201
|
+
epicId: directive.epicId,
|
|
202
|
+
executionBranch: directive.executionBranch,
|
|
203
|
+
originBranch: directive.originBranch,
|
|
204
|
+
graphRevision: directive.graphRevision,
|
|
205
|
+
originHeadSha: originBinding.originHeadSha,
|
|
206
|
+
executionHeadSha: actual.executionHeadSha,
|
|
207
|
+
acceptedCheckpointIds: actual.acceptedCheckpointIds,
|
|
208
|
+
acceptedCheckpointHeads: actualReconciliation.acceptedCheckpointHeads,
|
|
209
|
+
aggregateQaReceipt: aggregate,
|
|
210
|
+
nowIso: actual.nowIso ?? new Date(0).toISOString(),
|
|
211
|
+
}))) {
|
|
212
|
+
reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.AGGREGATE_QA_REQUIRED);
|
|
213
|
+
}
|
|
93
214
|
if (actual.writerLeaseActive)
|
|
94
215
|
reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.LEASE_ACTIVE);
|
|
95
216
|
if (!sameSet(directive.storyCheckpointIds, actual.acceptedCheckpointIds)) {
|
|
@@ -220,6 +341,9 @@ function nonEmpty(value) {
|
|
|
220
341
|
function isSha(value) {
|
|
221
342
|
return /^[a-f0-9]{7,64}$/i.test(value);
|
|
222
343
|
}
|
|
344
|
+
function isFullSha(value) {
|
|
345
|
+
return /^[a-f0-9]{40,64}$/i.test(value);
|
|
346
|
+
}
|
|
223
347
|
function isHash(value) {
|
|
224
348
|
return typeof value === 'string' && /^[a-f0-9]{64}$/i.test(value);
|
|
225
349
|
}
|
|
@@ -229,3 +353,21 @@ function unique(values) {
|
|
|
229
353
|
function sameSet(left, right) {
|
|
230
354
|
return left.length === right.length && [...left].sort().every((item, index) => item === [...right].sort()[index]);
|
|
231
355
|
}
|
|
356
|
+
function sameOrdered(left, right) {
|
|
357
|
+
return left.length === right.length && left.every((item, index) => item === right[index]);
|
|
358
|
+
}
|
|
359
|
+
function safeRepositoryPath(value) {
|
|
360
|
+
return safeWriteScope(value) && !value.endsWith('/');
|
|
361
|
+
}
|
|
362
|
+
function safeWriteScope(value) {
|
|
363
|
+
if (typeof value !== 'string' || value.length === 0 || value.length > 512
|
|
364
|
+
|| value.startsWith('/') || value.startsWith('-') || value.includes('\\')
|
|
365
|
+
|| value.includes('\0') || value.includes('//'))
|
|
366
|
+
return false;
|
|
367
|
+
const parts = value.replace(/\/$/, '').split('/');
|
|
368
|
+
return parts.length > 0 && parts.every((part) => part.length > 0 && part !== '.' && part !== '..')
|
|
369
|
+
&& parts[0] !== '.git';
|
|
370
|
+
}
|
|
371
|
+
function writeScopeCovers(scope, path) {
|
|
372
|
+
return scope === path || scope.endsWith('/') && path.startsWith(scope);
|
|
373
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex-root
|
|
3
|
-
description: "🧠 Neocortex Root Agent v4.60.
|
|
3
|
+
description: "🧠 Neocortex Root Agent v4.60.75 | OrNexus Team"
|
|
4
4
|
model: opus
|
|
5
5
|
color: blue
|
|
6
6
|
tools:
|
|
@@ -108,7 +108,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
108
108
|
┌────────────────────────────────────────────────────────────┐
|
|
109
109
|
│ │
|
|
110
110
|
│ ####### N E O C O R T E X │
|
|
111
|
-
│ ### ######## v4.60.
|
|
111
|
+
│ ### ######## v4.60.75 │
|
|
112
112
|
│ ######### ##### │
|
|
113
113
|
│ ## ############## Development Orchestrator │
|
|
114
114
|
│ ## ### ###### ## OrNexus Team │
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: neocortex
|
|
3
|
-
description: "🧠 Neocortex v4.60.
|
|
3
|
+
description: "🧠 Neocortex v4.60.75 | OrNexus Team"
|
|
4
4
|
model: opus
|
|
5
5
|
color: blue
|
|
6
6
|
permissionMode: bypassPermissions
|
|
@@ -104,7 +104,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
|
|
|
104
104
|
┌────────────────────────────────────────────────────────────┐
|
|
105
105
|
│ │
|
|
106
106
|
│ ####### N E O C O R T E X │
|
|
107
|
-
│ ### ######## v4.60.
|
|
107
|
+
│ ### ######## v4.60.75 │
|
|
108
108
|
│ ######### ##### │
|
|
109
109
|
│ ## ############## Development Orchestrator │
|
|
110
110
|
│ ## ### ###### ## OrNexus Team │
|