@ornexus/neocortex 4.60.23 → 4.60.24

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.
Files changed (84) hide show
  1. package/dist/sbom.cdx.json +23 -23
  2. package/install.js +67 -10
  3. package/install.ps1 +39 -8
  4. package/install.sh +18 -6
  5. package/package.json +5 -2
  6. package/packages/client/dist/adapters/adapter-registry.d.ts +2 -2
  7. package/packages/client/dist/adapters/adapter-registry.js +1 -1
  8. package/packages/client/dist/adapters/grok-adapter.d.ts +11 -0
  9. package/packages/client/dist/adapters/grok-adapter.js +2 -0
  10. package/packages/client/dist/adapters/index.d.ts +1 -0
  11. package/packages/client/dist/adapters/index.js +1 -1
  12. package/packages/client/dist/adapters/platform-detector.d.ts +1 -1
  13. package/packages/client/dist/adapters/platform-detector.js +1 -1
  14. package/packages/client/dist/agent/refresh-stubs.js +2 -2
  15. package/packages/client/dist/cli.js +21 -2
  16. package/packages/client/dist/commands/invoke.d.ts +20 -21
  17. package/packages/client/dist/commands/invoke.js +59 -55
  18. package/packages/client/dist/commands/story-checkpoint.d.ts +15 -0
  19. package/packages/client/dist/commands/story-checkpoint.js +1 -0
  20. package/packages/client/dist/config.js +1 -1
  21. package/packages/client/dist/generated/command-registry.generated.d.ts +18 -52
  22. package/packages/client/dist/generated/command-registry.generated.js +1 -1
  23. package/packages/client/dist/git/direct-yolo-checkpoint.d.ts +67 -0
  24. package/packages/client/dist/git/direct-yolo-checkpoint.js +3 -0
  25. package/packages/client/dist/git/git-lifecycle-store.d.ts +198 -0
  26. package/packages/client/dist/git/git-lifecycle-store.js +4 -0
  27. package/packages/client/dist/git/secure-filesystem-boundary.d.ts +26 -0
  28. package/packages/client/dist/git/secure-filesystem-boundary.js +123 -0
  29. package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -1
  30. package/packages/client/dist/index.d.ts +2 -0
  31. package/packages/client/dist/index.js +1 -1
  32. package/packages/client/dist/memory/shared-project-memory-types.d.ts +29 -2
  33. package/packages/client/dist/memory/shared-project-memory-types.js +2 -2
  34. package/packages/client/dist/policy/subagent-approval-policy.js +1 -1
  35. package/packages/client/dist/runner/headless/continuous-story-workspace.d.ts +131 -0
  36. package/packages/client/dist/runner/headless/continuous-story-workspace.js +58 -0
  37. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.d.ts +23 -0
  38. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -0
  39. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +15 -0
  40. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +28 -0
  41. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +12 -0
  42. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +8 -0
  43. package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +134 -0
  44. package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -0
  45. package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -1
  46. package/packages/client/dist/runner/headless/run-yolo.js +1 -1
  47. package/packages/client/dist/runner/headless/run-yoloop.d.ts +7 -2
  48. package/packages/client/dist/runner/headless/run-yoloop.js +8 -1
  49. package/packages/client/dist/runner/headless/types.d.ts +1 -1
  50. package/packages/client/dist/runner/headless/types.js +2 -2
  51. package/packages/client/dist/runner-cli.js +0 -0
  52. package/packages/client/dist/state/project-state-snapshot.js +1 -1
  53. package/packages/client/dist/state/state-json-repair.d.ts +9 -0
  54. package/packages/client/dist/state/state-json-repair.js +3 -3
  55. package/packages/client/dist/tier/tier-aware-client.js +1 -1
  56. package/packages/client/dist/yoloop/invoke-hooks.d.ts +13 -10
  57. package/packages/client/dist/yoloop/invoke-hooks.js +8 -5
  58. package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1
  59. package/packages/shared/dist/generated/command-registry.generated.js +18 -66
  60. package/packages/shared/dist/generated/invocation-schema.generated.js +5 -25
  61. package/packages/shared/dist/invocation/index.d.ts +1 -1
  62. package/packages/shared/dist/yoloop/epic-terminal-git.js +227 -0
  63. package/packages/shared/dist/yoloop/planning-graph.js +119 -0
  64. package/packages/shared/dist/yoloop/public-story-write-set.js +27 -0
  65. package/packages/shared/dist/yoloop/wave-decision-receipt.js +19 -0
  66. package/targets-stubs/antigravity/gemini.md +1 -1
  67. package/targets-stubs/antigravity/neocortex.md +18 -0
  68. package/targets-stubs/antigravity/skill/SKILL.md +1 -1
  69. package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
  70. package/targets-stubs/claude-code/neocortex-root.md +21 -2
  71. package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
  72. package/targets-stubs/claude-code/neocortex.md +2 -2
  73. package/targets-stubs/codex/AGENTS.md +20 -1
  74. package/targets-stubs/cursor/agent.md +20 -2
  75. package/targets-stubs/gemini-cli/agent.md +2 -2
  76. package/targets-stubs/gemini-cli/gemini.md +18 -0
  77. package/targets-stubs/grok/README.md +13 -0
  78. package/targets-stubs/grok/SKILL.md +50 -0
  79. package/targets-stubs/grok/config-mcp.toml +22 -0
  80. package/targets-stubs/grok/install-grok.sh +31 -0
  81. package/targets-stubs/kimi/neocortex.md +18 -0
  82. package/targets-stubs/openclaw/SKILL.md +18 -0
  83. package/targets-stubs/opencode/neocortex-root.md +20 -1
  84. package/targets-stubs/vscode/neocortex.agent.md +20 -2
@@ -1,41 +1,41 @@
1
1
  /** Generated by scripts/generate-command-registry.mjs. Do not edit. */
2
2
  export const COMMAND_REGISTRY_SCHEMA_VERSION = 1;
3
3
  export const COMMAND_REGISTRY_VERSION = "1.0.0";
4
- export const COMMAND_REGISTRY_CHECKSUM = "39c74bfd2ec67a12b19bda587ffcf6a987dfca1b6d33142a28988c574f7eb7c0";
4
+ export const COMMAND_REGISTRY_CHECKSUM = "5ed842e2bf9a9e959f23096cec199be4200bb4056b99479b5dc47b2dbe1293e6";
5
5
  export const COMMAND_REGISTRY_PROJECTION_MANIFEST = {
6
6
  "schemaVersion": 1,
7
7
  "registryVersion": "1.0.0",
8
- "registryChecksum": "39c74bfd2ec67a12b19bda587ffcf6a987dfca1b6d33142a28988c574f7eb7c0",
8
+ "registryChecksum": "5ed842e2bf9a9e959f23096cec199be4200bb4056b99479b5dc47b2dbe1293e6",
9
9
  "projections": [
10
10
  {
11
11
  "kind": "admin",
12
- "entryCount": 63,
13
- "sha256": "ca4b20573423f84de80a5664c0171d01b48d43fb3cb2041597a48ab44374dd5d"
12
+ "entryCount": 62,
13
+ "sha256": "d752e65aa65ee7864416b4c68af6d516233e180cd5b0408dcb244751ede7a21a"
14
14
  },
15
15
  {
16
16
  "kind": "client",
17
- "entryCount": 63,
18
- "sha256": "ca4b20573423f84de80a5664c0171d01b48d43fb3cb2041597a48ab44374dd5d"
17
+ "entryCount": 62,
18
+ "sha256": "d752e65aa65ee7864416b4c68af6d516233e180cd5b0408dcb244751ede7a21a"
19
19
  },
20
20
  {
21
21
  "kind": "docs",
22
- "entryCount": 63,
23
- "sha256": "ca4b20573423f84de80a5664c0171d01b48d43fb3cb2041597a48ab44374dd5d"
22
+ "entryCount": 62,
23
+ "sha256": "d752e65aa65ee7864416b4c68af6d516233e180cd5b0408dcb244751ede7a21a"
24
24
  },
25
25
  {
26
26
  "kind": "metrics",
27
- "entryCount": 63,
28
- "sha256": "ca4b20573423f84de80a5664c0171d01b48d43fb3cb2041597a48ab44374dd5d"
27
+ "entryCount": 62,
28
+ "sha256": "d752e65aa65ee7864416b4c68af6d516233e180cd5b0408dcb244751ede7a21a"
29
29
  },
30
30
  {
31
31
  "kind": "server",
32
- "entryCount": 68,
33
- "sha256": "4c10d04de88c08d694d1eaa6f43b688897dfaafd60dcdf155389a1903121465b"
32
+ "entryCount": 67,
33
+ "sha256": "1b3e29b3b462a8fb283a308e311ca681d7b106f986723d4c08b84805c878a00a"
34
34
  },
35
35
  {
36
36
  "kind": "shared",
37
- "entryCount": 68,
38
- "sha256": "3b9bde2f873434594c1aedebaa608d401f29729f14e962a9639760f0139bc60b"
37
+ "entryCount": 67,
38
+ "sha256": "0d181e8f869891e7c3e09b76ad00b122ca7c5a4ca530e86391d64517d14b7bc8"
39
39
  }
40
40
  ]
41
41
  };
@@ -2022,54 +2022,6 @@ export const GENERATED_SHARED_COMMANDS = [
2022
2022
  "visibility": "public",
2023
2023
  "subcommands": []
2024
2024
  },
2025
- {
2026
- "aliases": [
2027
- "inicializar"
2028
- ],
2029
- "category": "quick-start",
2030
- "compatibility": {
2031
- "deprecatedIn": null,
2032
- "introducedIn": "1.0.0",
2033
- "removedIn": null,
2034
- "replacement": null
2035
- },
2036
- "description": {
2037
- "en": "Initialize project",
2038
- "es": "Inicializar proyecto",
2039
- "pt-BR": "Inicializar projeto"
2040
- },
2041
- "examples": [
2042
- "@neocortex *init",
2043
- "@neocortex init",
2044
- "@neocortex 2"
2045
- ],
2046
- "id": "init",
2047
- "inputShape": "epics",
2048
- "mode": "utility",
2049
- "name": "Inicializar + Enrichment",
2050
- "number": 2,
2051
- "policy": {
2052
- "billingClass": "billable",
2053
- "idempotencyClass": "logical-supported",
2054
- "minimumTier": "free",
2055
- "mutationClass": "stateful",
2056
- "privilege": "authenticated",
2057
- "quotaClass": "workflow",
2058
- "replayClass": "signed-request",
2059
- "strictReadOnly": "deny"
2060
- },
2061
- "projections": [
2062
- "admin",
2063
- "client",
2064
- "docs",
2065
- "metrics",
2066
- "server",
2067
- "shared"
2068
- ],
2069
- "stepId": "step-u-init",
2070
- "visibility": "public",
2071
- "subcommands": []
2072
- },
2073
2025
  {
2074
2026
  "aliases": [
2075
2027
  "continuity-jobs",
@@ -3575,9 +3527,9 @@ export const GENERATED_SHARED_COMMANDS = [
3575
3527
  "replacement": null
3576
3528
  },
3577
3529
  "description": {
3578
- "en": "Setup branch",
3579
- "es": "Configurar branch",
3580
- "pt-BR": "Configurar branch"
3530
+ "en": "Set up branch in the current checkout",
3531
+ "es": "Configurar branch en el checkout actual",
3532
+ "pt-BR": "Configurar branch no checkout atual"
3581
3533
  },
3582
3534
  "examples": [
3583
3535
  "@neocortex *setup-branch @docs/stories/P126.01.story.md"
@@ -3585,7 +3537,7 @@ export const GENERATED_SHARED_COMMANDS = [
3585
3537
  "id": "setup-branch",
3586
3538
  "inputShape": "story",
3587
3539
  "mode": "step",
3588
- "name": "Configurar Branch & Worktree",
3540
+ "name": "Configurar Branch",
3589
3541
  "number": 24,
3590
3542
  "policy": {
3591
3543
  "billingClass": "billable",
@@ -2,13 +2,13 @@
2
2
  export const GENERATED_INVOCATION_SCHEMA_MANIFEST = {
3
3
  "schemaVersion": "p205-invocation-schema-v1",
4
4
  "registryVersion": "1.0.0",
5
- "registryChecksum": "39c74bfd2ec67a12b19bda587ffcf6a987dfca1b6d33142a28988c574f7eb7c0",
6
- "schemaChecksum": "14ea14ebfd79941609426b34690c0fade17034a4b1b166b14d985cb097ee7128",
7
- "commandCount": 63,
5
+ "registryChecksum": "5ed842e2bf9a9e959f23096cec199be4200bb4056b99479b5dc47b2dbe1293e6",
6
+ "schemaChecksum": "c3252fa75c16cc81bd0ea0e8b33868d121c2e45258f9b425c310af9337cfbd6f",
7
+ "commandCount": 62,
8
8
  "optionCount": 47,
9
- "positionalCount": 44,
9
+ "positionalCount": 43,
10
10
  "operationCount": 33,
11
- "projectionSha256": "3052d8fa2bdfcfcc8bca17ba1a5ad5ec39270064ca68760f691b36a9eb2b0ed0",
11
+ "projectionSha256": "9843f3f7155ed3a6244c020a324c2d2818c5d4fd2d7590eeb78b9e055bc18e75",
12
12
  "commands": [
13
13
  {
14
14
  "commandId": "arch-api-contracts",
@@ -830,26 +830,6 @@ export const GENERATED_INVOCATION_SCHEMA_MANIFEST = {
830
830
  ],
831
831
  "terminator": true
832
832
  },
833
- {
834
- "commandId": "init",
835
- "inputShape": "epics",
836
- "operation": {
837
- "required": false,
838
- "unknownAsPositional": false,
839
- "operations": []
840
- },
841
- "options": [],
842
- "positionals": [
843
- {
844
- "cardinality": "one",
845
- "id": "epics",
846
- "kind": "target-ref",
847
- "order": 0,
848
- "required": false
849
- }
850
- ],
851
- "terminator": true
852
- },
853
833
  {
854
834
  "commandId": "jobs",
855
835
  "inputShape": "continuity-jobs",
@@ -120,7 +120,7 @@ export interface InvocationCommandSchemaV1 {
120
120
  readonly positionals: readonly InvocationPositionalSchemaV1[];
121
121
  readonly terminator: true;
122
122
  }
123
- export declare const INVOCATION_SCHEMA_CHECKSUM: "14ea14ebfd79941609426b34690c0fade17034a4b1b166b14d985cb097ee7128";
123
+ export declare const INVOCATION_SCHEMA_CHECKSUM: "c3252fa75c16cc81bd0ea0e8b33868d121c2e45258f9b425c310af9337cfbd6f";
124
124
  export interface InvocationSchemaManifestV1 {
125
125
  readonly schemaVersion: typeof INVOCATION_SCHEMA_VERSION;
126
126
  readonly registryVersion: string;
@@ -0,0 +1,227 @@
1
+ /** Public contracts and pure safety decisions for epic-owned terminal Git. */
2
+ export const EPIC_TERMINAL_GIT_REASON_CODES = Object.freeze({
3
+ READY: 'epic-terminal-git-ready',
4
+ ALREADY_COMPLETE: 'epic-terminal-git-already-complete',
5
+ ORIGIN_MISSING: 'epic-origin-branch-missing',
6
+ EXECUTION_MISSING: 'epic-execution-branch-missing',
7
+ SAME_BRANCH: 'epic-origin-equals-execution',
8
+ LOCAL_GATES_REQUIRED: 'epic-local-gates-required',
9
+ STORY_CHECKPOINTS_REQUIRED: 'epic-story-checkpoints-required',
10
+ LEASE_ACTIVE: 'epic-writer-lease-active',
11
+ HEAD_MISMATCH: 'epic-execution-head-mismatch',
12
+ GRAPH_REVISION_MISMATCH: 'epic-graph-revision-mismatch',
13
+ MERGE_CONFLICT: 'epic-terminal-merge-conflict',
14
+ REMOTE_POLICY_DENIED: 'epic-terminal-remote-policy-denied',
15
+ RETRY_ELIGIBLE: 'epic-terminal-retry-eligible',
16
+ RECOVERED_PHYSICAL_PUSH: 'epic-terminal-recovered-physical-push',
17
+ OWNERSHIP_UNPROVEN: 'git-resource-ownership-unproven',
18
+ RESOURCE_ACTIVE: 'git-resource-active',
19
+ RESOURCE_ORIGIN: 'git-resource-is-origin',
20
+ RESOURCE_CURRENT: 'git-resource-is-current',
21
+ RESOURCE_PROTECTED: 'git-resource-protected',
22
+ UNIQUE_COMMITS: 'git-resource-has-unique-commits',
23
+ INTEGRATION_UNPROVEN: 'git-resource-integration-unproven',
24
+ SAFE_TO_RECONCILE: 'git-resource-safe-to-reconcile',
25
+ ALREADY_RECONCILED: 'git-resource-already-reconciled',
26
+ AGGREGATE_QA_REQUIRED: 'epic-aggregate-qa-receipt-required',
27
+ AGGREGATE_QA_STALE: 'epic-aggregate-qa-receipt-stale',
28
+ ORIGIN_BINDING_REQUIRED: 'epic-origin-binding-required',
29
+ PROVIDER_TRUTH_UNKNOWN: 'git-resource-provider-truth-unknown',
30
+ WORKTREE_ACTIVE: 'git-resource-worktree-active',
31
+ RESOURCE_RACED: 'git-resource-expected-oid-raced',
32
+ REMOTE_DELETE_CAS_UNAVAILABLE: 'git-resource-remote-delete-cas-unavailable',
33
+ ORIGIN_CAPTURE_WINDOW_MISSED: 'epic-origin-binding-capture-window-missed',
34
+ ORIGIN_PHYSICAL_DRIFT: 'epic-origin-binding-physical-drift',
35
+ PHYSICAL_REVALIDATION_REQUIRED: 'epic-terminal-physical-revalidation-required',
36
+ PHYSICAL_ANCESTRY_UNPROVEN: 'epic-terminal-physical-ancestry-unproven',
37
+ PR_STRICT_BASE_GUARD_REQUIRED: 'epic-terminal-pr-strict-base-guard-required',
38
+ PR_BASE_GUARD_UNVERIFIABLE: 'epic-terminal-pr-base-guard-unverifiable',
39
+ PR_MERGE_QUEUE_LOCAL_GATE_REQUIRED: 'epic-terminal-pr-merge-queue-local-gate-required',
40
+ });
41
+ export function validateEpicTerminalGitDirective(directive, actual) {
42
+ const reasons = [];
43
+ if (!nonEmpty(directive.originBranch))
44
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.ORIGIN_MISSING);
45
+ if (!nonEmpty(directive.executionBranch))
46
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.EXECUTION_MISSING);
47
+ if (directive.originBranch === directive.executionBranch)
48
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.SAME_BRANCH);
49
+ if (directive.localGates?.passed !== true || directive.localGates.receiptRefs.length === 0) {
50
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.LOCAL_GATES_REQUIRED);
51
+ }
52
+ const aggregate = actual.aggregateQaReceipt;
53
+ const directedAggregate = directive.localGates?.aggregateQaReceipt;
54
+ if (!aggregate
55
+ || aggregate.schemaVersion !== 1
56
+ || aggregate.evidenceVersion !== 'p205-execution-v2'
57
+ || aggregate.producer !== 'local-yolo-tdd'
58
+ || aggregate.contract !== 'P205-CI-02'
59
+ || aggregate.command !== 'node scripts/test-root.mjs --gate complete'
60
+ || aggregate.verdict !== 'passed'
61
+ || aggregate.executionHeadSha !== actual.executionHeadSha
62
+ || aggregate.executionHeadSha !== directive.expectedExecutionHeadSha
63
+ || aggregate.graphRevision !== directive.graphRevision
64
+ || aggregate.receiptRef.length === 0
65
+ || aggregate.gateIds.length === 0
66
+ || !isHash(aggregate.manifestDigest)
67
+ || !isHash(aggregate.resultDigest)
68
+ || !directedAggregate
69
+ || directedAggregate.executionHeadSha !== aggregate.executionHeadSha
70
+ || directedAggregate.graphRevision !== aggregate.graphRevision
71
+ || directedAggregate.checkedAt !== aggregate.checkedAt
72
+ || directedAggregate.receiptRef !== aggregate.receiptRef
73
+ || directedAggregate.manifestDigest !== aggregate.manifestDigest
74
+ || directedAggregate.resultDigest !== aggregate.resultDigest
75
+ || !sameSet(directedAggregate.gateIds, aggregate.gateIds)
76
+ || !directive.localGates.receiptRefs.includes(aggregate.receiptRef)) {
77
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.AGGREGATE_QA_REQUIRED);
78
+ }
79
+ else if (!Number.isFinite(Date.parse(aggregate.checkedAt)) || actual.nowIso && (Date.parse(actual.nowIso) - Date.parse(aggregate.checkedAt) > 30 * 60 * 1000
80
+ || Date.parse(aggregate.checkedAt) - Date.parse(actual.nowIso) > 5 * 60 * 1000)) {
81
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.AGGREGATE_QA_STALE);
82
+ }
83
+ const originBinding = actual.originBinding;
84
+ if (!originBinding
85
+ || originBinding.schemaVersion !== 1
86
+ || originBinding.capturedFromCurrentCheckout !== true
87
+ || originBinding.originBranch !== directive.originBranch
88
+ || originBinding.executionBranch !== directive.executionBranch
89
+ || !isSha(originBinding.originHeadSha)
90
+ || !Number.isFinite(Date.parse(originBinding.capturedAt))) {
91
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.ORIGIN_BINDING_REQUIRED);
92
+ }
93
+ if (actual.writerLeaseActive)
94
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.LEASE_ACTIVE);
95
+ if (!sameSet(directive.storyCheckpointIds, actual.acceptedCheckpointIds)) {
96
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.STORY_CHECKPOINTS_REQUIRED);
97
+ }
98
+ if (!isSha(directive.expectedExecutionHeadSha) || directive.expectedExecutionHeadSha !== actual.executionHeadSha) {
99
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.HEAD_MISMATCH);
100
+ }
101
+ if (directive.graphRevision && directive.graphRevision !== actual.graphRevision) {
102
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.GRAPH_REVISION_MISMATCH);
103
+ }
104
+ if (!/^[a-f0-9]{64}$/i.test(directive.graphRevision))
105
+ reasons.push(EPIC_TERMINAL_GIT_REASON_CODES.GRAPH_REVISION_MISMATCH);
106
+ if (actual.existingReceipt?.physicalStatus === 'pushed'
107
+ && actual.existingReceipt.idempotencyKey === directive.idempotencyKey
108
+ && actual.existingReceipt.executionHeadSha === directive.expectedExecutionHeadSha) {
109
+ return { ready: true, reasonCodes: [EPIC_TERMINAL_GIT_REASON_CODES.ALREADY_COMPLETE] };
110
+ }
111
+ return reasons.length === 0
112
+ ? { ready: true, reasonCodes: [EPIC_TERMINAL_GIT_REASON_CODES.READY] }
113
+ : { ready: false, reasonCodes: unique(reasons) };
114
+ }
115
+ /**
116
+ * Fail-closed ownership and integration classifier. A canonical-looking name is
117
+ * never sufficient: state/receipt proof plus convention and provider metadata
118
+ * or PR head/base evidence are required before any destructive action.
119
+ */
120
+ export function classifyGitReconciliationCandidate(candidate) {
121
+ const evidence = unique(candidate.ownershipEvidence);
122
+ const hasDurableProof = evidence.includes('state_reference') || evidence.includes('terminal_receipt');
123
+ const hasConvention = evidence.includes('canonical_convention');
124
+ const hasCorroboration = candidate.kind === 'pull_request'
125
+ ? evidence.includes('pr_head_base_match')
126
+ : evidence.includes('managed_metadata');
127
+ const managed = hasDurableProof && hasConvention && hasCorroboration;
128
+ const preserve = (...reasonCodes) => Object.freeze({
129
+ schemaVersion: 1,
130
+ resourceId: candidate.resourceId,
131
+ action: 'preserve',
132
+ managed,
133
+ reasonCodes: Object.freeze(unique(reasonCodes)),
134
+ evidence: Object.freeze(evidence),
135
+ publicSafe: true,
136
+ });
137
+ if (candidate.lifecycle === 'already_absent' && candidate.providerVerified) {
138
+ return Object.freeze({ schemaVersion: 1, resourceId: candidate.resourceId, action: 'no_op', managed, reasonCodes: [EPIC_TERMINAL_GIT_REASON_CODES.ALREADY_RECONCILED], evidence, publicSafe: true });
139
+ }
140
+ if (!managed)
141
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.OWNERSHIP_UNPROVEN);
142
+ if (!candidate.providerVerified)
143
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.PROVIDER_TRUTH_UNKNOWN);
144
+ if (candidate.origin)
145
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.RESOURCE_ORIGIN);
146
+ if (candidate.current)
147
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.RESOURCE_CURRENT);
148
+ if (candidate.worktreeActive)
149
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.WORKTREE_ACTIVE);
150
+ if (candidate.protected)
151
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.RESOURCE_PROTECTED);
152
+ if (candidate.lifecycle === 'active')
153
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.RESOURCE_ACTIVE);
154
+ if (candidate.hasExclusiveCommits)
155
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.UNIQUE_COMMITS);
156
+ if (candidate.previouslyReconciled)
157
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.RESOURCE_RACED);
158
+ if (!candidate.commitsReachable && !candidate.contentEquivalent) {
159
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.INTEGRATION_UNPROVEN);
160
+ }
161
+ // Generic Git deletion has no safe expected-OID guard without force flags.
162
+ // The GitHub capability guards both target and integration origin atomically.
163
+ if (candidate.kind === 'remote_branch' && candidate.remoteDeletionCas !== 'github-update-refs-v1') {
164
+ return preserve(EPIC_TERMINAL_GIT_REASON_CODES.REMOTE_DELETE_CAS_UNAVAILABLE);
165
+ }
166
+ const action = candidate.kind === 'local_branch'
167
+ ? 'delete_local_branch'
168
+ : candidate.kind === 'remote_branch' ? 'delete_remote_branch' : 'close_pull_request';
169
+ return Object.freeze({
170
+ schemaVersion: 1,
171
+ resourceId: candidate.resourceId,
172
+ action,
173
+ managed: true,
174
+ reasonCodes: [EPIC_TERMINAL_GIT_REASON_CODES.SAFE_TO_RECONCILE],
175
+ evidence: Object.freeze(evidence),
176
+ publicSafe: true,
177
+ });
178
+ }
179
+ export function reconcileTerminalReceipt(current, requested) {
180
+ if (!current)
181
+ return { kind: 'accepted', receipt: requested };
182
+ if (current.idempotencyKey !== requested.idempotencyKey)
183
+ return { kind: 'accepted', receipt: requested };
184
+ if (current.epicId === requested.epicId
185
+ && current.executionBranch === requested.executionBranch
186
+ && current.originBranch === requested.originBranch
187
+ && current.baseSha === requested.baseSha
188
+ && current.executionHeadSha === requested.executionHeadSha
189
+ && current.mergeSha === requested.mergeSha
190
+ && current.pushedSha === requested.pushedSha
191
+ && current.physicalStatus === requested.physicalStatus) {
192
+ if (requested.candidateQa && JSON.stringify(current.candidateQa) !== JSON.stringify(requested.candidateQa)) {
193
+ return { kind: 'accepted', receipt: requested };
194
+ }
195
+ if (requested.providerGuard && JSON.stringify(current.providerGuard) !== JSON.stringify(requested.providerGuard)) {
196
+ return { kind: 'accepted', receipt: requested };
197
+ }
198
+ return { kind: 'reused', receipt: current };
199
+ }
200
+ // A failed/prepared attempt is not integrated physical truth. The root has to
201
+ // revalidate a new candidate, but its successful retry must replace that debt.
202
+ // Never rewrite a pushed/merged receipt or move an idempotency key to a new owner.
203
+ if (current.retryEligible && !current.pushedSha
204
+ && ['prepared', 'blocked_local_or_repo', 'denied_external_gate'].includes(current.physicalStatus)
205
+ && current.epicId === requested.epicId
206
+ && current.executionBranch === requested.executionBranch
207
+ && current.originBranch === requested.originBranch
208
+ && current.executionHeadSha === requested.executionHeadSha) {
209
+ return { kind: 'accepted', receipt: requested };
210
+ }
211
+ return { kind: 'blocked', reasonCode: 'epic-terminal-receipt-idempotency-conflict' };
212
+ }
213
+ function nonEmpty(value) {
214
+ return typeof value === 'string' && value.trim().length > 0;
215
+ }
216
+ function isSha(value) {
217
+ return /^[a-f0-9]{7,64}$/i.test(value);
218
+ }
219
+ function isHash(value) {
220
+ return typeof value === 'string' && /^[a-f0-9]{64}$/i.test(value);
221
+ }
222
+ function unique(values) {
223
+ return [...new Set(values)];
224
+ }
225
+ function sameSet(left, right) {
226
+ return left.length === right.length && [...left].sort().every((item, index) => item === [...right].sort()[index]);
227
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * P208.01 -- public-safe planning evidence for intelligent epic waves.
3
+ *
4
+ * This module normalizes evidence only. It never authorizes concurrency or
5
+ * mutates state; the planner must treat `evidence: unknown` conservatively.
6
+ */
7
+ import { createHash } from 'node:crypto';
8
+ export const YOLOOP_PLANNING_GRAPH_VERSION = 1;
9
+ export const YOLOOP_MAX_WRITE_CONCURRENCY = 1;
10
+ const CLAIM_KINDS = new Set([
11
+ 'file', 'module', 'contract', 'schema', 'api', 'migration', 'manifest',
12
+ 'generated-file', 'lockfile', 'global-state', 'tool', 'service', 'port',
13
+ 'database', 'fixture', 'human-gate', 'side-effect',
14
+ ]);
15
+ const ACCESSES = new Set(['read', 'write', 'exclusive']);
16
+ const EVIDENCE = new Set(['verified', 'declared', 'unknown']);
17
+ const MAX_CLAIMS = 128;
18
+ const MAX_ATTEMPTS = 32;
19
+ export function normalizeYoloopStoryPlanningEvidence(value) {
20
+ const dependencyBasis = EVIDENCE.has(value?.dependencyBasis)
21
+ ? value?.dependencyBasis
22
+ : 'unknown';
23
+ const claims = uniqueSortedClaims((value?.claims ?? []).slice(0, MAX_CLAIMS).map(normalizeClaim));
24
+ const semanticArtifacts = uniqueSortedSemantic((value?.semanticArtifacts ?? []).slice(0, MAX_CLAIMS).map(normalizeSemantic));
25
+ const attempts = normalizeAttempts(value?.attempts ?? []);
26
+ const normalized = {
27
+ schemaVersion: YOLOOP_PLANNING_GRAPH_VERSION,
28
+ dependencyBasis,
29
+ claims,
30
+ semanticArtifacts,
31
+ ...(boundedInteger(value?.priority, -1_000, 1_000) !== undefined ? { priority: boundedInteger(value?.priority, -1_000, 1_000) } : {}),
32
+ ...(boundedInteger(value?.estimatedCost, 0, 1_000_000) !== undefined ? { estimatedCost: boundedInteger(value?.estimatedCost, 0, 1_000_000) } : {}),
33
+ ...(isRisk(value?.risk) ? { risk: value.risk } : { risk: 'unknown' }),
34
+ ...(attempts.length > 0 ? { attempts } : {}),
35
+ };
36
+ return { ...normalized, graphRevision: revisionFor(normalized) };
37
+ }
38
+ export function normalizeYoloopPlanningCapacity(value) {
39
+ return {
40
+ supportsReadOnlyParallel: value?.supportsReadOnlyParallel === true,
41
+ supportsIsolatedBuildTest: value?.supportsIsolatedBuildTest === true,
42
+ supportsPreparedBundles: value?.supportsPreparedBundles === true,
43
+ maxPreparationConcurrency: positiveBounded(value?.maxPreparationConcurrency, 1, 64),
44
+ maxBuildTestConcurrency: positiveBounded(value?.maxBuildTestConcurrency, 1, 64),
45
+ maxWriteConcurrency: YOLOOP_MAX_WRITE_CONCURRENCY,
46
+ };
47
+ }
48
+ export function normalizeYoloopPlanningBudget(value) {
49
+ const maxEstimatedCost = boundedInteger(value?.maxEstimatedCost, 0, 1_000_000);
50
+ const remainingEstimatedCost = boundedInteger(value?.remainingEstimatedCost, 0, 1_000_000);
51
+ return {
52
+ maxStories: positiveBounded(value?.maxStories, 1, 64),
53
+ ...(maxEstimatedCost !== undefined ? { maxEstimatedCost } : {}),
54
+ ...(remainingEstimatedCost !== undefined ? { remainingEstimatedCost } : {}),
55
+ };
56
+ }
57
+ function normalizeClaim(value) {
58
+ const kind = CLAIM_KINDS.has(value.kind) ? value.kind : 'global-state';
59
+ const access = ACCESSES.has(value.access) ? value.access : 'exclusive';
60
+ const evidence = EVIDENCE.has(value.evidence) ? value.evidence : 'unknown';
61
+ const ref = safeRef(value.ref) || 'unknown';
62
+ const globalSensitive = value.globalSensitive === true || isGlobalSensitive(kind, ref);
63
+ return { kind, ref, access, evidence, ...(globalSensitive ? { globalSensitive: true } : {}) };
64
+ }
65
+ function normalizeSemantic(value) {
66
+ return {
67
+ ref: safeRef(value.ref) || 'unknown',
68
+ direction: value.direction === 'produces' || value.direction === 'consumes' ? value.direction : 'consumes',
69
+ evidence: EVIDENCE.has(value.evidence) ? value.evidence : 'unknown',
70
+ };
71
+ }
72
+ function normalizeAttempts(values) {
73
+ return values.slice(-MAX_ATTEMPTS).map((value, index) => ({
74
+ attempt: positiveBounded(value.attempt, index + 1, 1_000_000),
75
+ outcome: ['passed', 'failed', 'blocked', 'cancelled', 'rolled-back'].includes(value.outcome) ? value.outcome : 'blocked',
76
+ reasonCodes: uniqueStrings(value.reasonCodes).slice(0, 32),
77
+ ...(value.discoveredClaims ? { discoveredClaims: uniqueSortedClaims(value.discoveredClaims.slice(0, MAX_CLAIMS).map(normalizeClaim)) } : {}),
78
+ }));
79
+ }
80
+ function safeRef(value) {
81
+ if (typeof value !== 'string')
82
+ return '';
83
+ const trimmed = value.trim().replace(/\\/g, '/');
84
+ if (!trimmed || trimmed.length > 240 || trimmed.startsWith('/') || trimmed.includes('..') || /[\u0000-\u001f]/.test(trimmed))
85
+ return '';
86
+ return /^[A-Za-z0-9._/:@#-]+$/.test(trimmed) ? trimmed : '';
87
+ }
88
+ function isGlobalSensitive(kind, ref) {
89
+ return ['migration', 'manifest', 'generated-file', 'lockfile', 'global-state'].includes(kind) ||
90
+ /(^|\/)(package-lock\.json|pnpm-lock\.yaml|yarn\.lock|migrations?|generated)(\/|$)/i.test(ref);
91
+ }
92
+ function uniqueSortedClaims(values) {
93
+ return uniqueBy(values, (value) => `${value.kind}:${value.ref}:${value.access}:${value.evidence}:${value.globalSensitive === true}`)
94
+ .sort((a, b) => `${a.kind}:${a.ref}:${a.access}`.localeCompare(`${b.kind}:${b.ref}:${b.access}`));
95
+ }
96
+ function uniqueSortedSemantic(values) {
97
+ return uniqueBy(values, (value) => `${value.ref}:${value.direction}:${value.evidence}`)
98
+ .sort((a, b) => `${a.ref}:${a.direction}`.localeCompare(`${b.ref}:${b.direction}`));
99
+ }
100
+ function uniqueStrings(values) {
101
+ return [...new Set(values.map(safeRef).filter(Boolean))].sort((a, b) => a.localeCompare(b));
102
+ }
103
+ function uniqueBy(values, key) {
104
+ const seen = new Set();
105
+ return values.filter((value) => { const next = key(value); if (seen.has(next))
106
+ return false; seen.add(next); return true; });
107
+ }
108
+ function isRisk(value) {
109
+ return value === 'low' || value === 'normal' || value === 'high' || value === 'critical' || value === 'unknown';
110
+ }
111
+ function boundedInteger(value, min, max) {
112
+ return typeof value === 'number' && Number.isInteger(value) && value >= min && value <= max ? value : undefined;
113
+ }
114
+ function positiveBounded(value, fallback, max) {
115
+ return boundedInteger(value, 1, max) ?? fallback;
116
+ }
117
+ function revisionFor(value) {
118
+ return createHash('sha256').update(JSON.stringify(value)).digest('hex');
119
+ }
@@ -0,0 +1,27 @@
1
+ import { normalizeContinuousWriteRef } from './wave-decision-receipt.js';
2
+ export function publicWriteSet(story) {
3
+ const claimRefs = (story.planning?.claims ?? [])
4
+ .filter((claim) => claim.access !== 'read' && claim.evidence === 'verified')
5
+ .map((claim) => claim.ref);
6
+ const authoredRefs = [
7
+ ...claimRefs,
8
+ ...(story.files_to_modify ?? []),
9
+ ...(story.contracts ?? []),
10
+ ...(story.contract_refs ?? []),
11
+ ...(story.shared_surfaces ?? []),
12
+ ].map(normalizeContinuousWriteRef);
13
+ // Never reduce an invalid authored scope to only the lifecycle paths.
14
+ if (authoredRefs.some((ref) => ref === undefined))
15
+ return [];
16
+ return [...new Set([
17
+ '.neocortex/state.json',
18
+ `docs/stories/${safeRef(story.id)}.story.md`,
19
+ ...authoredRefs,
20
+ ])].sort();
21
+ }
22
+ function safeRef(value) {
23
+ if (typeof value !== 'string')
24
+ return '';
25
+ const normalized = value.trim().replace(/\\/g, '/');
26
+ return normalized && normalized.length <= 240 && !normalized.startsWith('/') && !normalized.includes('..') && /^[A-Za-z0-9._/:@#-]+$/.test(normalized) ? normalized : '';
27
+ }
@@ -1,5 +1,16 @@
1
1
  /** P208.03 -- public-safe deterministic planning DecisionReceipts. */
2
2
  import { createHash } from 'node:crypto';
3
+ /** Canonical public write-path boundary, shipped with bundle admission to every client. */
4
+ export function normalizeContinuousWriteRef(value) {
5
+ if (typeof value !== 'string')
6
+ return undefined;
7
+ const normalized = value.replace(/\\/g, '/');
8
+ if (!normalized || normalized.length > 240 || normalized.startsWith('/')
9
+ || /^[A-Za-z]:/.test(normalized) || normalized.includes('..') || normalized.includes('//')
10
+ || normalized.split('/').includes('.') || !/^[A-Za-z0-9._/:@#-]+$/.test(normalized))
11
+ return undefined;
12
+ return normalized;
13
+ }
3
14
  export const YOLOOP_WAVE_DECISION_RECEIPT_VERSION = 1;
4
15
  export function createYoloopWaveDecisionReceipt(input) {
5
16
  const epicId = requireId(input.epicId, 'epic-id-invalid');
@@ -42,6 +53,13 @@ export function validateYoloopPreparationBundle(bundle, expected) {
42
53
  errors.push('bundle-graph-stale');
43
54
  if (![bundle.baseSha, bundle.bundleDigest, bundle.graphRevision, bundle.claimRevision].every(isHash))
44
55
  errors.push('bundle-digest-invalid');
56
+ if (!Array.isArray(bundle.authorizedWriteSet) || bundle.authorizedWriteSet.length === 0
57
+ || bundle.authorizedWriteSet.some((ref) => typeof ref !== 'string' || normalizeContinuousWriteRef(ref) !== ref)
58
+ || expected.authorizedWriteSet && !sameStrings(bundle.authorizedWriteSet, expected.authorizedWriteSet))
59
+ errors.push('bundle-write-set-invalid');
60
+ if (!bundle.contextDigests || typeof bundle.contextDigests !== 'object'
61
+ || Object.entries(bundle.contextDigests).some(([path, digest]) => normalizeContinuousWriteRef(path) !== path || !isHash(digest)))
62
+ errors.push('bundle-context-digests-invalid');
45
63
  if (!isTimestamp(bundle.createdAt) || !isTimestamp(bundle.expiresAt) || bundle.expiresAt <= expected.nowIso || bundle.expiresAt <= bundle.createdAt)
46
64
  errors.push('bundle-expired');
47
65
  if (!Array.isArray(bundle.validationRefs) || bundle.validationRefs.length === 0 || bundle.validationRefs.some((ref) => !isSafeRef(ref)))
@@ -75,3 +93,4 @@ function isHash(value) { return /^[a-f0-9]{40,64}$/.test(value); }
75
93
  function isTimestamp(value) { return typeof value === 'string' && Number.isFinite(Date.parse(value)); }
76
94
  function isSafeRef(value) { return typeof value === 'string' && value.length > 0 && value.length <= 200 && !value.startsWith('/') && !value.includes('..') && /^[A-Za-z0-9._/:@#-]+$/.test(value); }
77
95
  function uniqueSafe(values) { return Object.freeze([...new Set(values)].sort()); }
96
+ function sameStrings(left, right) { return left.length === right.length && left.every((value, index) => value === right[index]); }
@@ -1,4 +1,4 @@
1
- # 🧠 Neocortex v4.60.23 | OrNexus Team
1
+ # 🧠 Neocortex v4.60.24 | OrNexus Team
2
2
 
3
3
  This project uses Neocortex, a Development Orchestrator.
4
4
 
@@ -52,3 +52,21 @@ history, ambient metadata, raw logs, or raw stdout/stderr into this profile. Do
52
52
  not pass unmanaged user-owned content. Do not embed, reveal, summarize, or reconstruct proprietary prompts, server-side
53
53
  implementation details, orchestration logic, secrets, license keys, or customer
54
54
  data. This child must not invoke another Neocortex child.
55
+
56
+ At the root only, `epicTerminalGitDirective` uses the recorded origin and
57
+ forbids worktree management, force-push and ambiguous/unintegrated cleanup.
58
+ `epicGitReconciliationDirective` runs fail-closed before start/resume children
59
+ and supports explicit `dryRun` audit without Git effects.
60
+ Terminal effects require a fresh aggregate-QA receipt bound to the exact physical
61
+ execution HEAD/current graph and an immutable physical origin binding. PR reuse
62
+ and cleanup revalidate exact SHAs and fresh provider/ref truth immediately before
63
+ effects; active, manual-worktree, ambiguous, protected or raced resources remain.
64
+ Post-commit lease/checkpoint and physical receipts use the fsync/CAS runtime store
65
+ in a private user-owned directory inside the Git common-dir, never a tracked-state rewrite. Accepted story checkpoints
66
+ require independent typed QA and root commit-range review receipts bound to the
67
+ story, commit range, bundle digest and graph revision; fresh physical recomputation is authoritative and generic receipts cannot
68
+ authorize pass/approval. Persisted merge state never replaces fresh root physical
69
+ verification when a terminal-complete response carries the terminal directive.
70
+ Remote branch deletion is
71
+ preserved with `git-resource-remote-delete-cas-unavailable` when no OID-bound
72
+ provider primitive exists; local refs and PRs still reconcile when fully proven.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: neocortex
3
- description: "🧠 Neocortex v4.60.23 | OrNexus Team"
3
+ description: "🧠 Neocortex v4.60.24 | OrNexus Team"
4
4
  ---
5
5
 
6
6
  <!--
@@ -4,7 +4,7 @@ agent:
4
4
  name: 'Neocortex Root Agent'
5
5
  title: 'Development Orchestrator (Root)'
6
6
  icon: '>'
7
- version: '4.60.23'
7
+ version: '4.60.24'
8
8
  architecture: 'thin-client'
9
9
  module: stand-alone
10
10
  hasSidecar: false