@rpamis/comet 0.4.0-beta.10 → 0.4.0-beta.11
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/assets/manifest.json +1 -1
- package/assets/skills/comet/reference/classic-layout.md +1 -1
- package/assets/skills/comet/scripts/comet-entry-runtime.mjs +1 -1
- package/assets/skills/comet/scripts/comet-hook-router.mjs +179 -879
- package/assets/skills/comet/scripts/comet-runtime.mjs +3 -3
- package/assets/skills/comet-native/SKILL.md +1 -2
- package/assets/skills/comet-native/reference/commands.md +2 -4
- package/assets/skills/comet-native/scripts/comet-native-runtime.mjs +4482 -4785
- package/assets/skills-zh/comet/reference/classic-layout.md +1 -1
- package/assets/skills-zh/comet-native/SKILL.md +1 -2
- package/assets/skills-zh/comet-native/reference/commands.md +2 -4
- package/dist/app/commands/update.d.ts.map +1 -1
- package/dist/app/commands/update.js +14 -2
- package/dist/app/commands/update.js.map +1 -1
- package/dist/domains/comet-classic/classic-layout-initialization.js +3 -3
- package/dist/domains/comet-classic/classic-layout-initialization.js.map +1 -1
- package/dist/domains/comet-entry/init-workflow.d.ts.map +1 -1
- package/dist/domains/comet-entry/init-workflow.js +17 -3
- package/dist/domains/comet-entry/init-workflow.js.map +1 -1
- package/dist/domains/comet-native/native-change.d.ts +0 -2
- package/dist/domains/comet-native/native-change.d.ts.map +1 -1
- package/dist/domains/comet-native/native-change.js +8 -104
- package/dist/domains/comet-native/native-change.js.map +1 -1
- package/dist/domains/comet-native/native-cli.d.ts.map +1 -1
- package/dist/domains/comet-native/native-cli.js +3 -47
- package/dist/domains/comet-native/native-cli.js.map +1 -1
- package/dist/domains/comet-native/native-controller-trust.d.ts +0 -1
- package/dist/domains/comet-native/native-controller-trust.d.ts.map +1 -1
- package/dist/domains/comet-native/native-controller-trust.js +2 -15
- package/dist/domains/comet-native/native-controller-trust.js.map +1 -1
- package/dist/domains/comet-native/native-review-trust.d.ts +1 -1
- package/dist/domains/comet-native/native-review-trust.d.ts.map +1 -1
- package/dist/domains/comet-native/native-review-trust.js +1 -1
- package/dist/domains/comet-native/native-review-trust.js.map +1 -1
- package/dist/domains/comet-native/native-snapshot.d.ts.map +1 -1
- package/dist/domains/comet-native/native-snapshot.js +0 -37
- package/dist/domains/comet-native/native-snapshot.js.map +1 -1
- package/dist/domains/comet-native/native-types.d.ts +1 -10
- package/dist/domains/comet-native/native-types.d.ts.map +1 -1
- package/dist/domains/comet-native/native-verification-runtime.d.ts.map +1 -1
- package/dist/domains/comet-native/native-verification-runtime.js +3 -3
- package/dist/domains/comet-native/native-verification-runtime.js.map +1 -1
- package/dist/domains/skill/platform-install.d.ts.map +1 -1
- package/dist/domains/skill/platform-install.js +22 -2
- package/dist/domains/skill/platform-install.js.map +1 -1
- package/dist/domains/workflow-contract/project-config.d.ts.map +1 -1
- package/dist/domains/workflow-contract/project-config.js +4 -4
- package/dist/domains/workflow-contract/project-config.js.map +1 -1
- package/eval/local/tasks/comet-native-workflow/instruction.md +4 -5
- package/eval/local/tasks/comet-native-workflow/validation/test_native_workflow.py +2 -2
- package/eval/local/tests/conftest.py +1 -26
- package/eval/local/tests/scaffold/test_native_wave_evaluations.py +2 -17
- package/package.json +1 -1
- package/dist/domains/comet-native/native-creation-authorization.d.ts +0 -30
- package/dist/domains/comet-native/native-creation-authorization.d.ts.map +0 -1
- package/dist/domains/comet-native/native-creation-authorization.js +0 -110
- package/dist/domains/comet-native/native-creation-authorization.js.map +0 -1
|
@@ -126,17 +126,17 @@ var require_visit = __commonJS({
|
|
|
126
126
|
visit.BREAK = BREAK;
|
|
127
127
|
visit.SKIP = SKIP;
|
|
128
128
|
visit.REMOVE = REMOVE;
|
|
129
|
-
function visit_(key, node, visitor,
|
|
130
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
129
|
+
function visit_(key, node, visitor, path19) {
|
|
130
|
+
const ctrl = callVisitor(key, node, visitor, path19);
|
|
131
131
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
132
|
-
replaceNode(key,
|
|
133
|
-
return visit_(key, ctrl, visitor,
|
|
132
|
+
replaceNode(key, path19, ctrl);
|
|
133
|
+
return visit_(key, ctrl, visitor, path19);
|
|
134
134
|
}
|
|
135
135
|
if (typeof ctrl !== "symbol") {
|
|
136
136
|
if (identity.isCollection(node)) {
|
|
137
|
-
|
|
137
|
+
path19 = Object.freeze(path19.concat(node));
|
|
138
138
|
for (let i = 0; i < node.items.length; ++i) {
|
|
139
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
139
|
+
const ci = visit_(i, node.items[i], visitor, path19);
|
|
140
140
|
if (typeof ci === "number")
|
|
141
141
|
i = ci - 1;
|
|
142
142
|
else if (ci === BREAK)
|
|
@@ -147,13 +147,13 @@ var require_visit = __commonJS({
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
} else if (identity.isPair(node)) {
|
|
150
|
-
|
|
151
|
-
const ck = visit_("key", node.key, visitor,
|
|
150
|
+
path19 = Object.freeze(path19.concat(node));
|
|
151
|
+
const ck = visit_("key", node.key, visitor, path19);
|
|
152
152
|
if (ck === BREAK)
|
|
153
153
|
return BREAK;
|
|
154
154
|
else if (ck === REMOVE)
|
|
155
155
|
node.key = null;
|
|
156
|
-
const cv = visit_("value", node.value, visitor,
|
|
156
|
+
const cv = visit_("value", node.value, visitor, path19);
|
|
157
157
|
if (cv === BREAK)
|
|
158
158
|
return BREAK;
|
|
159
159
|
else if (cv === REMOVE)
|
|
@@ -174,17 +174,17 @@ var require_visit = __commonJS({
|
|
|
174
174
|
visitAsync.BREAK = BREAK;
|
|
175
175
|
visitAsync.SKIP = SKIP;
|
|
176
176
|
visitAsync.REMOVE = REMOVE;
|
|
177
|
-
async function visitAsync_(key, node, visitor,
|
|
178
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
177
|
+
async function visitAsync_(key, node, visitor, path19) {
|
|
178
|
+
const ctrl = await callVisitor(key, node, visitor, path19);
|
|
179
179
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
180
|
-
replaceNode(key,
|
|
181
|
-
return visitAsync_(key, ctrl, visitor,
|
|
180
|
+
replaceNode(key, path19, ctrl);
|
|
181
|
+
return visitAsync_(key, ctrl, visitor, path19);
|
|
182
182
|
}
|
|
183
183
|
if (typeof ctrl !== "symbol") {
|
|
184
184
|
if (identity.isCollection(node)) {
|
|
185
|
-
|
|
185
|
+
path19 = Object.freeze(path19.concat(node));
|
|
186
186
|
for (let i = 0; i < node.items.length; ++i) {
|
|
187
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
187
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path19);
|
|
188
188
|
if (typeof ci === "number")
|
|
189
189
|
i = ci - 1;
|
|
190
190
|
else if (ci === BREAK)
|
|
@@ -195,13 +195,13 @@ var require_visit = __commonJS({
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
} else if (identity.isPair(node)) {
|
|
198
|
-
|
|
199
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
198
|
+
path19 = Object.freeze(path19.concat(node));
|
|
199
|
+
const ck = await visitAsync_("key", node.key, visitor, path19);
|
|
200
200
|
if (ck === BREAK)
|
|
201
201
|
return BREAK;
|
|
202
202
|
else if (ck === REMOVE)
|
|
203
203
|
node.key = null;
|
|
204
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
204
|
+
const cv = await visitAsync_("value", node.value, visitor, path19);
|
|
205
205
|
if (cv === BREAK)
|
|
206
206
|
return BREAK;
|
|
207
207
|
else if (cv === REMOVE)
|
|
@@ -228,23 +228,23 @@ var require_visit = __commonJS({
|
|
|
228
228
|
}
|
|
229
229
|
return visitor;
|
|
230
230
|
}
|
|
231
|
-
function callVisitor(key, node, visitor,
|
|
231
|
+
function callVisitor(key, node, visitor, path19) {
|
|
232
232
|
if (typeof visitor === "function")
|
|
233
|
-
return visitor(key, node,
|
|
233
|
+
return visitor(key, node, path19);
|
|
234
234
|
if (identity.isMap(node))
|
|
235
|
-
return visitor.Map?.(key, node,
|
|
235
|
+
return visitor.Map?.(key, node, path19);
|
|
236
236
|
if (identity.isSeq(node))
|
|
237
|
-
return visitor.Seq?.(key, node,
|
|
237
|
+
return visitor.Seq?.(key, node, path19);
|
|
238
238
|
if (identity.isPair(node))
|
|
239
|
-
return visitor.Pair?.(key, node,
|
|
239
|
+
return visitor.Pair?.(key, node, path19);
|
|
240
240
|
if (identity.isScalar(node))
|
|
241
|
-
return visitor.Scalar?.(key, node,
|
|
241
|
+
return visitor.Scalar?.(key, node, path19);
|
|
242
242
|
if (identity.isAlias(node))
|
|
243
|
-
return visitor.Alias?.(key, node,
|
|
243
|
+
return visitor.Alias?.(key, node, path19);
|
|
244
244
|
return void 0;
|
|
245
245
|
}
|
|
246
|
-
function replaceNode(key,
|
|
247
|
-
const parent =
|
|
246
|
+
function replaceNode(key, path19, node) {
|
|
247
|
+
const parent = path19[path19.length - 1];
|
|
248
248
|
if (identity.isCollection(parent)) {
|
|
249
249
|
parent.items[key] = node;
|
|
250
250
|
} else if (identity.isPair(parent)) {
|
|
@@ -854,10 +854,10 @@ var require_Collection = __commonJS({
|
|
|
854
854
|
var createNode = require_createNode();
|
|
855
855
|
var identity = require_identity();
|
|
856
856
|
var Node = require_Node();
|
|
857
|
-
function collectionFromPath(schema,
|
|
857
|
+
function collectionFromPath(schema, path19, value) {
|
|
858
858
|
let v = value;
|
|
859
|
-
for (let i =
|
|
860
|
-
const k =
|
|
859
|
+
for (let i = path19.length - 1; i >= 0; --i) {
|
|
860
|
+
const k = path19[i];
|
|
861
861
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
862
862
|
const a = [];
|
|
863
863
|
a[k] = v;
|
|
@@ -876,7 +876,7 @@ var require_Collection = __commonJS({
|
|
|
876
876
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
877
877
|
});
|
|
878
878
|
}
|
|
879
|
-
var isEmptyPath = (
|
|
879
|
+
var isEmptyPath = (path19) => path19 == null || typeof path19 === "object" && !!path19[Symbol.iterator]().next().done;
|
|
880
880
|
var Collection = class extends Node.NodeBase {
|
|
881
881
|
constructor(type, schema) {
|
|
882
882
|
super(type);
|
|
@@ -906,11 +906,11 @@ var require_Collection = __commonJS({
|
|
|
906
906
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
907
907
|
* that already exists in the map.
|
|
908
908
|
*/
|
|
909
|
-
addIn(
|
|
910
|
-
if (isEmptyPath(
|
|
909
|
+
addIn(path19, value) {
|
|
910
|
+
if (isEmptyPath(path19))
|
|
911
911
|
this.add(value);
|
|
912
912
|
else {
|
|
913
|
-
const [key, ...rest] =
|
|
913
|
+
const [key, ...rest] = path19;
|
|
914
914
|
const node = this.get(key, true);
|
|
915
915
|
if (identity.isCollection(node))
|
|
916
916
|
node.addIn(rest, value);
|
|
@@ -924,8 +924,8 @@ var require_Collection = __commonJS({
|
|
|
924
924
|
* Removes a value from the collection.
|
|
925
925
|
* @returns `true` if the item was found and removed.
|
|
926
926
|
*/
|
|
927
|
-
deleteIn(
|
|
928
|
-
const [key, ...rest] =
|
|
927
|
+
deleteIn(path19) {
|
|
928
|
+
const [key, ...rest] = path19;
|
|
929
929
|
if (rest.length === 0)
|
|
930
930
|
return this.delete(key);
|
|
931
931
|
const node = this.get(key, true);
|
|
@@ -939,8 +939,8 @@ var require_Collection = __commonJS({
|
|
|
939
939
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
940
940
|
* `true` (collections are always returned intact).
|
|
941
941
|
*/
|
|
942
|
-
getIn(
|
|
943
|
-
const [key, ...rest] =
|
|
942
|
+
getIn(path19, keepScalar) {
|
|
943
|
+
const [key, ...rest] = path19;
|
|
944
944
|
const node = this.get(key, true);
|
|
945
945
|
if (rest.length === 0)
|
|
946
946
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -958,8 +958,8 @@ var require_Collection = __commonJS({
|
|
|
958
958
|
/**
|
|
959
959
|
* Checks if the collection includes a value with the key `key`.
|
|
960
960
|
*/
|
|
961
|
-
hasIn(
|
|
962
|
-
const [key, ...rest] =
|
|
961
|
+
hasIn(path19) {
|
|
962
|
+
const [key, ...rest] = path19;
|
|
963
963
|
if (rest.length === 0)
|
|
964
964
|
return this.has(key);
|
|
965
965
|
const node = this.get(key, true);
|
|
@@ -969,8 +969,8 @@ var require_Collection = __commonJS({
|
|
|
969
969
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
970
970
|
* boolean to add/remove the item from the set.
|
|
971
971
|
*/
|
|
972
|
-
setIn(
|
|
973
|
-
const [key, ...rest] =
|
|
972
|
+
setIn(path19, value) {
|
|
973
|
+
const [key, ...rest] = path19;
|
|
974
974
|
if (rest.length === 0) {
|
|
975
975
|
this.set(key, value);
|
|
976
976
|
} else {
|
|
@@ -3485,9 +3485,9 @@ var require_Document = __commonJS({
|
|
|
3485
3485
|
this.contents.add(value);
|
|
3486
3486
|
}
|
|
3487
3487
|
/** Adds a value to the document. */
|
|
3488
|
-
addIn(
|
|
3488
|
+
addIn(path19, value) {
|
|
3489
3489
|
if (assertCollection(this.contents))
|
|
3490
|
-
this.contents.addIn(
|
|
3490
|
+
this.contents.addIn(path19, value);
|
|
3491
3491
|
}
|
|
3492
3492
|
/**
|
|
3493
3493
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -3562,14 +3562,14 @@ var require_Document = __commonJS({
|
|
|
3562
3562
|
* Removes a value from the document.
|
|
3563
3563
|
* @returns `true` if the item was found and removed.
|
|
3564
3564
|
*/
|
|
3565
|
-
deleteIn(
|
|
3566
|
-
if (Collection.isEmptyPath(
|
|
3565
|
+
deleteIn(path19) {
|
|
3566
|
+
if (Collection.isEmptyPath(path19)) {
|
|
3567
3567
|
if (this.contents == null)
|
|
3568
3568
|
return false;
|
|
3569
3569
|
this.contents = null;
|
|
3570
3570
|
return true;
|
|
3571
3571
|
}
|
|
3572
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3572
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path19) : false;
|
|
3573
3573
|
}
|
|
3574
3574
|
/**
|
|
3575
3575
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -3584,10 +3584,10 @@ var require_Document = __commonJS({
|
|
|
3584
3584
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
3585
3585
|
* `true` (collections are always returned intact).
|
|
3586
3586
|
*/
|
|
3587
|
-
getIn(
|
|
3588
|
-
if (Collection.isEmptyPath(
|
|
3587
|
+
getIn(path19, keepScalar) {
|
|
3588
|
+
if (Collection.isEmptyPath(path19))
|
|
3589
3589
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3590
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3590
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path19, keepScalar) : void 0;
|
|
3591
3591
|
}
|
|
3592
3592
|
/**
|
|
3593
3593
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -3598,10 +3598,10 @@ var require_Document = __commonJS({
|
|
|
3598
3598
|
/**
|
|
3599
3599
|
* Checks if the document includes a value at `path`.
|
|
3600
3600
|
*/
|
|
3601
|
-
hasIn(
|
|
3602
|
-
if (Collection.isEmptyPath(
|
|
3601
|
+
hasIn(path19) {
|
|
3602
|
+
if (Collection.isEmptyPath(path19))
|
|
3603
3603
|
return this.contents !== void 0;
|
|
3604
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3604
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path19) : false;
|
|
3605
3605
|
}
|
|
3606
3606
|
/**
|
|
3607
3607
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -3618,13 +3618,13 @@ var require_Document = __commonJS({
|
|
|
3618
3618
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
3619
3619
|
* boolean to add/remove the item from the set.
|
|
3620
3620
|
*/
|
|
3621
|
-
setIn(
|
|
3622
|
-
if (Collection.isEmptyPath(
|
|
3621
|
+
setIn(path19, value) {
|
|
3622
|
+
if (Collection.isEmptyPath(path19)) {
|
|
3623
3623
|
this.contents = value;
|
|
3624
3624
|
} else if (this.contents == null) {
|
|
3625
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3625
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path19), value);
|
|
3626
3626
|
} else if (assertCollection(this.contents)) {
|
|
3627
|
-
this.contents.setIn(
|
|
3627
|
+
this.contents.setIn(path19, value);
|
|
3628
3628
|
}
|
|
3629
3629
|
}
|
|
3630
3630
|
/**
|
|
@@ -5584,9 +5584,9 @@ var require_cst_visit = __commonJS({
|
|
|
5584
5584
|
visit.BREAK = BREAK;
|
|
5585
5585
|
visit.SKIP = SKIP;
|
|
5586
5586
|
visit.REMOVE = REMOVE;
|
|
5587
|
-
visit.itemAtPath = (cst,
|
|
5587
|
+
visit.itemAtPath = (cst, path19) => {
|
|
5588
5588
|
let item = cst;
|
|
5589
|
-
for (const [field2, index] of
|
|
5589
|
+
for (const [field2, index] of path19) {
|
|
5590
5590
|
const tok = item?.[field2];
|
|
5591
5591
|
if (tok && "items" in tok) {
|
|
5592
5592
|
item = tok.items[index];
|
|
@@ -5595,23 +5595,23 @@ var require_cst_visit = __commonJS({
|
|
|
5595
5595
|
}
|
|
5596
5596
|
return item;
|
|
5597
5597
|
};
|
|
5598
|
-
visit.parentCollection = (cst,
|
|
5599
|
-
const parent = visit.itemAtPath(cst,
|
|
5600
|
-
const field2 =
|
|
5598
|
+
visit.parentCollection = (cst, path19) => {
|
|
5599
|
+
const parent = visit.itemAtPath(cst, path19.slice(0, -1));
|
|
5600
|
+
const field2 = path19[path19.length - 1][0];
|
|
5601
5601
|
const coll = parent?.[field2];
|
|
5602
5602
|
if (coll && "items" in coll)
|
|
5603
5603
|
return coll;
|
|
5604
5604
|
throw new Error("Parent collection not found");
|
|
5605
5605
|
};
|
|
5606
|
-
function _visit(
|
|
5607
|
-
let ctrl = visitor(item,
|
|
5606
|
+
function _visit(path19, item, visitor) {
|
|
5607
|
+
let ctrl = visitor(item, path19);
|
|
5608
5608
|
if (typeof ctrl === "symbol")
|
|
5609
5609
|
return ctrl;
|
|
5610
5610
|
for (const field2 of ["key", "value"]) {
|
|
5611
5611
|
const token = item[field2];
|
|
5612
5612
|
if (token && "items" in token) {
|
|
5613
5613
|
for (let i = 0; i < token.items.length; ++i) {
|
|
5614
|
-
const ci = _visit(Object.freeze(
|
|
5614
|
+
const ci = _visit(Object.freeze(path19.concat([[field2, i]])), token.items[i], visitor);
|
|
5615
5615
|
if (typeof ci === "number")
|
|
5616
5616
|
i = ci - 1;
|
|
5617
5617
|
else if (ci === BREAK)
|
|
@@ -5622,10 +5622,10 @@ var require_cst_visit = __commonJS({
|
|
|
5622
5622
|
}
|
|
5623
5623
|
}
|
|
5624
5624
|
if (typeof ctrl === "function" && field2 === "key")
|
|
5625
|
-
ctrl = ctrl(item,
|
|
5625
|
+
ctrl = ctrl(item, path19);
|
|
5626
5626
|
}
|
|
5627
5627
|
}
|
|
5628
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5628
|
+
return typeof ctrl === "function" ? ctrl(item, path19) : ctrl;
|
|
5629
5629
|
}
|
|
5630
5630
|
exports.visit = visit;
|
|
5631
5631
|
}
|
|
@@ -6927,14 +6927,14 @@ var require_parser = __commonJS({
|
|
|
6927
6927
|
case "scalar":
|
|
6928
6928
|
case "single-quoted-scalar":
|
|
6929
6929
|
case "double-quoted-scalar": {
|
|
6930
|
-
const
|
|
6930
|
+
const fs14 = this.flowScalar(this.type);
|
|
6931
6931
|
if (atNextItem || it.value) {
|
|
6932
|
-
map.items.push({ start, key:
|
|
6932
|
+
map.items.push({ start, key: fs14, sep: [] });
|
|
6933
6933
|
this.onKeyLine = true;
|
|
6934
6934
|
} else if (it.sep) {
|
|
6935
|
-
this.stack.push(
|
|
6935
|
+
this.stack.push(fs14);
|
|
6936
6936
|
} else {
|
|
6937
|
-
Object.assign(it, { key:
|
|
6937
|
+
Object.assign(it, { key: fs14, sep: [] });
|
|
6938
6938
|
this.onKeyLine = true;
|
|
6939
6939
|
}
|
|
6940
6940
|
return;
|
|
@@ -7062,13 +7062,13 @@ var require_parser = __commonJS({
|
|
|
7062
7062
|
case "scalar":
|
|
7063
7063
|
case "single-quoted-scalar":
|
|
7064
7064
|
case "double-quoted-scalar": {
|
|
7065
|
-
const
|
|
7065
|
+
const fs14 = this.flowScalar(this.type);
|
|
7066
7066
|
if (!it || it.value)
|
|
7067
|
-
fc.items.push({ start: [], key:
|
|
7067
|
+
fc.items.push({ start: [], key: fs14, sep: [] });
|
|
7068
7068
|
else if (it.sep)
|
|
7069
|
-
this.stack.push(
|
|
7069
|
+
this.stack.push(fs14);
|
|
7070
7070
|
else
|
|
7071
|
-
Object.assign(it, { key:
|
|
7071
|
+
Object.assign(it, { key: fs14, sep: [] });
|
|
7072
7072
|
return;
|
|
7073
7073
|
}
|
|
7074
7074
|
case "flow-map-end":
|
|
@@ -7398,7 +7398,7 @@ function normalizeWorkflowArtifactRoot(value) {
|
|
|
7398
7398
|
const segments = projectRelativeSegments(value, "native.artifact_root");
|
|
7399
7399
|
return segments.length === 0 ? "." : segments.join("/");
|
|
7400
7400
|
}
|
|
7401
|
-
function normalizeClassicArtifactLayout(value, fallback = "
|
|
7401
|
+
function normalizeClassicArtifactLayout(value, fallback = "docs") {
|
|
7402
7402
|
const resolved = value ?? fallback;
|
|
7403
7403
|
if (resolved !== "legacy" && resolved !== "docs") {
|
|
7404
7404
|
throw new Error("classic.artifact_layout must be legacy or docs");
|
|
@@ -8475,8 +8475,8 @@ var init_state = __esm({
|
|
|
8475
8475
|
});
|
|
8476
8476
|
|
|
8477
8477
|
// domains/comet-entry/hook-router-entry.ts
|
|
8478
|
-
import
|
|
8479
|
-
import { promises as
|
|
8478
|
+
import path18 from "path";
|
|
8479
|
+
import { promises as fs13 } from "fs";
|
|
8480
8480
|
|
|
8481
8481
|
// domains/comet-native/native-paths.ts
|
|
8482
8482
|
init_project_config();
|
|
@@ -8939,12 +8939,12 @@ function addTarget(targets, value) {
|
|
|
8939
8939
|
function collectTargets(input, args) {
|
|
8940
8940
|
const targets = [];
|
|
8941
8941
|
const records = [args, input].filter(isRecord);
|
|
8942
|
-
for (const
|
|
8943
|
-
for (const key of SINGULAR_PATH_KEYS) addTarget(targets,
|
|
8944
|
-
for (const key of PLURAL_PATH_KEYS) addTarget(targets,
|
|
8945
|
-
for (const key of NESTED_TARGET_KEYS) addTarget(targets,
|
|
8942
|
+
for (const record3 of records) {
|
|
8943
|
+
for (const key of SINGULAR_PATH_KEYS) addTarget(targets, record3[key]);
|
|
8944
|
+
for (const key of PLURAL_PATH_KEYS) addTarget(targets, record3[key]);
|
|
8945
|
+
for (const key of NESTED_TARGET_KEYS) addTarget(targets, record3[key]);
|
|
8946
8946
|
for (const key of PATCH_KEYS) {
|
|
8947
|
-
const value =
|
|
8947
|
+
const value = record3[key];
|
|
8948
8948
|
if (typeof value === "string") targets.push(...patchTargets(value));
|
|
8949
8949
|
}
|
|
8950
8950
|
}
|
|
@@ -9147,9 +9147,9 @@ async function resolveBranchBinding(changeDir, options) {
|
|
|
9147
9147
|
if (document.errors.length > 0) {
|
|
9148
9148
|
throw new Error(`Invalid .comet.yaml: ${document.errors[0].message}`);
|
|
9149
9149
|
}
|
|
9150
|
-
const
|
|
9151
|
-
const isolation = typeof
|
|
9152
|
-
const boundBranch = typeof
|
|
9150
|
+
const record3 = document.toJS() ?? {};
|
|
9151
|
+
const isolation = typeof record3.isolation === "string" ? record3.isolation : null;
|
|
9152
|
+
const boundBranch = typeof record3.bound_branch === "string" && record3.bound_branch !== "" ? record3.bound_branch : null;
|
|
9153
9153
|
const bindingRequired = requiresBranchBinding(isolation);
|
|
9154
9154
|
const currentBranch = liveGitBranch(options.cwd);
|
|
9155
9155
|
const gitWorkTree = bindingRequired && boundBranch === null && currentBranch === null ? isGitWorkTree(options.cwd) : true;
|
|
@@ -10232,14 +10232,13 @@ async function inspectClassicHookGuard(projectRoot, changeName, request) {
|
|
|
10232
10232
|
}
|
|
10233
10233
|
|
|
10234
10234
|
// domains/comet-native/native-hook-guard.ts
|
|
10235
|
-
import { promises as
|
|
10236
|
-
import
|
|
10235
|
+
import { promises as fs12 } from "fs";
|
|
10236
|
+
import path17 from "path";
|
|
10237
10237
|
|
|
10238
10238
|
// domains/comet-native/native-change.ts
|
|
10239
10239
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
10240
|
-
import {
|
|
10241
|
-
import
|
|
10242
|
-
import path18 from "path";
|
|
10240
|
+
import { promises as fs11 } from "fs";
|
|
10241
|
+
import path16 from "path";
|
|
10243
10242
|
|
|
10244
10243
|
// domains/comet-native/native-bounded-file.ts
|
|
10245
10244
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -10451,528 +10450,6 @@ async function readNativeBoundedTextFile(options) {
|
|
|
10451
10450
|
}
|
|
10452
10451
|
}
|
|
10453
10452
|
|
|
10454
|
-
// domains/comet-native/native-canonical-hash.ts
|
|
10455
|
-
import { createHash as createHash3 } from "crypto";
|
|
10456
|
-
function invalidCanonicalJson(detail) {
|
|
10457
|
-
throw new TypeError(`Value is not valid canonical JSON: ${detail}`);
|
|
10458
|
-
}
|
|
10459
|
-
function canonicalArray(value, ancestors) {
|
|
10460
|
-
if (ancestors.has(value)) invalidCanonicalJson("cyclic structures are not supported");
|
|
10461
|
-
ancestors.add(value);
|
|
10462
|
-
try {
|
|
10463
|
-
const enumerableKeys = Object.keys(value);
|
|
10464
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
10465
|
-
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
10466
|
-
invalidCanonicalJson("sparse arrays are not supported");
|
|
10467
|
-
}
|
|
10468
|
-
}
|
|
10469
|
-
if (enumerableKeys.length !== value.length || enumerableKeys.some((key, index) => key !== String(index))) {
|
|
10470
|
-
invalidCanonicalJson("arrays must not have named enumerable properties");
|
|
10471
|
-
}
|
|
10472
|
-
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
10473
|
-
invalidCanonicalJson("symbol properties are not supported");
|
|
10474
|
-
}
|
|
10475
|
-
return `[${value.map((entry) => canonicalValue(entry, ancestors)).join(",")}]`;
|
|
10476
|
-
} finally {
|
|
10477
|
-
ancestors.delete(value);
|
|
10478
|
-
}
|
|
10479
|
-
}
|
|
10480
|
-
function canonicalObject(value, ancestors) {
|
|
10481
|
-
const prototype = Object.getPrototypeOf(value);
|
|
10482
|
-
if (prototype !== Object.prototype && prototype !== null) {
|
|
10483
|
-
invalidCanonicalJson("only plain objects are supported");
|
|
10484
|
-
}
|
|
10485
|
-
if (ancestors.has(value)) invalidCanonicalJson("cyclic structures are not supported");
|
|
10486
|
-
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
10487
|
-
invalidCanonicalJson("symbol properties are not supported");
|
|
10488
|
-
}
|
|
10489
|
-
ancestors.add(value);
|
|
10490
|
-
try {
|
|
10491
|
-
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
10492
|
-
const keys = Object.keys(value).sort();
|
|
10493
|
-
const fields = keys.map((key) => {
|
|
10494
|
-
const descriptor = descriptors[key];
|
|
10495
|
-
if (!descriptor || !("value" in descriptor)) {
|
|
10496
|
-
invalidCanonicalJson("accessor properties are not supported");
|
|
10497
|
-
}
|
|
10498
|
-
return `${JSON.stringify(key)}:${canonicalValue(descriptor.value, ancestors)}`;
|
|
10499
|
-
});
|
|
10500
|
-
return `{${fields.join(",")}}`;
|
|
10501
|
-
} finally {
|
|
10502
|
-
ancestors.delete(value);
|
|
10503
|
-
}
|
|
10504
|
-
}
|
|
10505
|
-
function canonicalValue(value, ancestors) {
|
|
10506
|
-
if (value === null) return "null";
|
|
10507
|
-
switch (typeof value) {
|
|
10508
|
-
case "boolean":
|
|
10509
|
-
return value ? "true" : "false";
|
|
10510
|
-
case "string":
|
|
10511
|
-
return JSON.stringify(value);
|
|
10512
|
-
case "number":
|
|
10513
|
-
if (!Number.isFinite(value)) invalidCanonicalJson("numbers must be finite");
|
|
10514
|
-
return JSON.stringify(Object.is(value, -0) ? 0 : value);
|
|
10515
|
-
case "object":
|
|
10516
|
-
return Array.isArray(value) ? canonicalArray(value, ancestors) : canonicalObject(value, ancestors);
|
|
10517
|
-
case "bigint":
|
|
10518
|
-
case "function":
|
|
10519
|
-
case "symbol":
|
|
10520
|
-
case "undefined":
|
|
10521
|
-
return invalidCanonicalJson(`${typeof value} values are not supported`);
|
|
10522
|
-
}
|
|
10523
|
-
return invalidCanonicalJson("unsupported value type");
|
|
10524
|
-
}
|
|
10525
|
-
function canonicalJson(value) {
|
|
10526
|
-
return canonicalValue(value, /* @__PURE__ */ new Set());
|
|
10527
|
-
}
|
|
10528
|
-
function canonicalHash(tag, value) {
|
|
10529
|
-
if (tag.length === 0) throw new TypeError("Canonical hash tag must be non-empty");
|
|
10530
|
-
if (/[\r\n]/u.test(tag)) {
|
|
10531
|
-
throw new TypeError("Canonical hash tag must not contain a line break");
|
|
10532
|
-
}
|
|
10533
|
-
return createHash3("sha256").update(`${tag}
|
|
10534
|
-
${canonicalJson(value)}`).digest("hex");
|
|
10535
|
-
}
|
|
10536
|
-
|
|
10537
|
-
// domains/comet-native/native-controller-trust.ts
|
|
10538
|
-
init_race_safe_read();
|
|
10539
|
-
import { promises as fs11 } from "node:fs";
|
|
10540
|
-
import os2 from "node:os";
|
|
10541
|
-
import path15 from "node:path";
|
|
10542
|
-
|
|
10543
|
-
// platform/fs/trusted-readonly-file.ts
|
|
10544
|
-
import { constants as fsConstants2, promises as fs10 } from "node:fs";
|
|
10545
|
-
import path14 from "node:path";
|
|
10546
|
-
function trustedReadonlyPosixFactsIssue(facts) {
|
|
10547
|
-
if (facts.fileUid === facts.currentUid) {
|
|
10548
|
-
return "Trusted file must be owned by a different host identity";
|
|
10549
|
-
}
|
|
10550
|
-
if ((facts.fileMode & 18) !== 0 || facts.fileWritable) {
|
|
10551
|
-
return "Trusted file is writable by the current process";
|
|
10552
|
-
}
|
|
10553
|
-
if (facts.parents.some(
|
|
10554
|
-
(parent) => parent.uid === facts.currentUid || (parent.mode & 18) !== 0 || parent.writable
|
|
10555
|
-
)) {
|
|
10556
|
-
return "Trusted file parent chain is writable by the current process";
|
|
10557
|
-
}
|
|
10558
|
-
return null;
|
|
10559
|
-
}
|
|
10560
|
-
var testHostIsolatedFiles = /* @__PURE__ */ new Set();
|
|
10561
|
-
function sameIdentity(left, right) {
|
|
10562
|
-
return left.realPath === right.realPath && left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs;
|
|
10563
|
-
}
|
|
10564
|
-
async function currentProcessCanWrite(file) {
|
|
10565
|
-
try {
|
|
10566
|
-
await fs10.access(file, fsConstants2.W_OK);
|
|
10567
|
-
return true;
|
|
10568
|
-
} catch (error) {
|
|
10569
|
-
if (error.code === "EACCES" || error.code === "EPERM") {
|
|
10570
|
-
return false;
|
|
10571
|
-
}
|
|
10572
|
-
throw error;
|
|
10573
|
-
}
|
|
10574
|
-
}
|
|
10575
|
-
async function inspectIdentity(file) {
|
|
10576
|
-
const [stat, realPath] = await Promise.all([fs10.lstat(file), fs10.realpath(file)]);
|
|
10577
|
-
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
10578
|
-
throw new Error("Trusted file capability requires a regular non-symlink file");
|
|
10579
|
-
}
|
|
10580
|
-
return {
|
|
10581
|
-
realPath,
|
|
10582
|
-
dev: stat.dev,
|
|
10583
|
-
ino: stat.ino,
|
|
10584
|
-
size: stat.size,
|
|
10585
|
-
mtimeMs: stat.mtimeMs
|
|
10586
|
-
};
|
|
10587
|
-
}
|
|
10588
|
-
async function assertTrustedReadonlyFile(options) {
|
|
10589
|
-
const identity = await inspectIdentity(options.file);
|
|
10590
|
-
if (options.previous && !sameIdentity(options.previous, identity)) {
|
|
10591
|
-
throw new Error("Trusted file identity changed while reading");
|
|
10592
|
-
}
|
|
10593
|
-
if (process.env.NODE_ENV === "test" && testHostIsolatedFiles.has(path14.resolve(options.file))) {
|
|
10594
|
-
return identity;
|
|
10595
|
-
}
|
|
10596
|
-
if (process.platform === "win32") {
|
|
10597
|
-
throw new Error(
|
|
10598
|
-
"Trusted file isolation cannot be proven from Windows file mode; use a host read-only mount capability"
|
|
10599
|
-
);
|
|
10600
|
-
}
|
|
10601
|
-
const currentUid = process.geteuid?.() ?? process.getuid?.();
|
|
10602
|
-
if (currentUid === void 0) {
|
|
10603
|
-
throw new Error("Trusted file owner isolation is unavailable on this platform");
|
|
10604
|
-
}
|
|
10605
|
-
const fileStat = await fs10.stat(identity.realPath);
|
|
10606
|
-
const parents = [];
|
|
10607
|
-
let directory = path14.dirname(identity.realPath);
|
|
10608
|
-
for (; ; ) {
|
|
10609
|
-
const stat = await fs10.lstat(directory);
|
|
10610
|
-
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
10611
|
-
throw new Error("Trusted file parent chain is not a physical directory chain");
|
|
10612
|
-
}
|
|
10613
|
-
parents.push({
|
|
10614
|
-
uid: stat.uid,
|
|
10615
|
-
mode: stat.mode,
|
|
10616
|
-
writable: await currentProcessCanWrite(directory)
|
|
10617
|
-
});
|
|
10618
|
-
const parent = path14.dirname(directory);
|
|
10619
|
-
if (parent === directory) break;
|
|
10620
|
-
directory = parent;
|
|
10621
|
-
}
|
|
10622
|
-
const issue = trustedReadonlyPosixFactsIssue({
|
|
10623
|
-
currentUid,
|
|
10624
|
-
fileUid: fileStat.uid,
|
|
10625
|
-
fileMode: fileStat.mode,
|
|
10626
|
-
fileWritable: await currentProcessCanWrite(identity.realPath),
|
|
10627
|
-
parents
|
|
10628
|
-
});
|
|
10629
|
-
if (issue) throw new Error(issue);
|
|
10630
|
-
return identity;
|
|
10631
|
-
}
|
|
10632
|
-
|
|
10633
|
-
// domains/comet-native/native-review-identity.ts
|
|
10634
|
-
import {
|
|
10635
|
-
createHash as createHash4,
|
|
10636
|
-
createPrivateKey,
|
|
10637
|
-
createPublicKey,
|
|
10638
|
-
generateKeyPairSync,
|
|
10639
|
-
sign as cryptoSign,
|
|
10640
|
-
verify as cryptoVerify
|
|
10641
|
-
} from "node:crypto";
|
|
10642
|
-
var NATIVE_REVIEW_IDENTITY_SCHEMA = "comet.native.review-identity.v1";
|
|
10643
|
-
var NATIVE_REVIEW_SIGNATURE_SCHEMA = "comet.native.review-signature.v1";
|
|
10644
|
-
var ALGORITHM = "ed25519";
|
|
10645
|
-
var HASH_PATTERN = /^[a-f0-9]{64}$/u;
|
|
10646
|
-
var MAX_PUBLIC_KEY_TEXT = 512;
|
|
10647
|
-
var MAX_SIGNATURE_TEXT = 256;
|
|
10648
|
-
var SIGNATURE_CONTEXT = Buffer.from("comet.native.review-payload.v1\0", "utf8");
|
|
10649
|
-
function record(value, label) {
|
|
10650
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
10651
|
-
throw new Error(`${label} must be an object`);
|
|
10652
|
-
}
|
|
10653
|
-
return value;
|
|
10654
|
-
}
|
|
10655
|
-
function exactKeys(value, expected, label) {
|
|
10656
|
-
const actual = Object.keys(value).sort();
|
|
10657
|
-
const canonical = [...expected].sort();
|
|
10658
|
-
if (JSON.stringify(actual) !== JSON.stringify(canonical)) {
|
|
10659
|
-
throw new Error(`${label} fields are invalid`);
|
|
10660
|
-
}
|
|
10661
|
-
}
|
|
10662
|
-
function sha2562(value) {
|
|
10663
|
-
return createHash4("sha256").update(value).digest("hex");
|
|
10664
|
-
}
|
|
10665
|
-
function payloadHash(value, label = "Native review payloadHash") {
|
|
10666
|
-
if (typeof value !== "string" || !HASH_PATTERN.test(value)) {
|
|
10667
|
-
throw new Error(`${label} must be a lowercase SHA-256 hash`);
|
|
10668
|
-
}
|
|
10669
|
-
return value;
|
|
10670
|
-
}
|
|
10671
|
-
function canonicalBase64(value, label, maxCharacters, expectedBytes) {
|
|
10672
|
-
if (typeof value !== "string" || value.length === 0 || value.length > maxCharacters || value.length % 4 !== 0) {
|
|
10673
|
-
throw new Error(`${label} is invalid`);
|
|
10674
|
-
}
|
|
10675
|
-
const bytes = Buffer.from(value, "base64");
|
|
10676
|
-
if (bytes.length === 0 || bytes.toString("base64") !== value || expectedBytes !== void 0 && bytes.length !== expectedBytes) {
|
|
10677
|
-
throw new Error(`${label} must use canonical base64`);
|
|
10678
|
-
}
|
|
10679
|
-
return bytes;
|
|
10680
|
-
}
|
|
10681
|
-
function publicKeyMaterial(value) {
|
|
10682
|
-
const supplied = canonicalBase64(value, "Native review public key", MAX_PUBLIC_KEY_TEXT);
|
|
10683
|
-
let key;
|
|
10684
|
-
try {
|
|
10685
|
-
key = createPublicKey({ key: supplied, format: "der", type: "spki" });
|
|
10686
|
-
} catch (error) {
|
|
10687
|
-
throw new Error("Native review public key is invalid", { cause: error });
|
|
10688
|
-
}
|
|
10689
|
-
if (key.type !== "public" || key.asymmetricKeyType !== "ed25519") {
|
|
10690
|
-
throw new Error("Native review public key must be Ed25519");
|
|
10691
|
-
}
|
|
10692
|
-
const der = key.export({ format: "der", type: "spki" });
|
|
10693
|
-
if (!Buffer.isBuffer(der) || !supplied.equals(der)) {
|
|
10694
|
-
throw new Error("Native review public key must use canonical SPKI DER");
|
|
10695
|
-
}
|
|
10696
|
-
return { key, der, text: der.toString("base64") };
|
|
10697
|
-
}
|
|
10698
|
-
function signaturePayload(hash) {
|
|
10699
|
-
return Buffer.concat([SIGNATURE_CONTEXT, Buffer.from(hash, "hex")]);
|
|
10700
|
-
}
|
|
10701
|
-
function parseNativeReviewSignature(value) {
|
|
10702
|
-
const root = record(value, "Native review signature");
|
|
10703
|
-
exactKeys(
|
|
10704
|
-
root,
|
|
10705
|
-
["schema", "algorithm", "keyId", "payloadHash", "signature"],
|
|
10706
|
-
"Native review signature"
|
|
10707
|
-
);
|
|
10708
|
-
if (root.schema !== NATIVE_REVIEW_SIGNATURE_SCHEMA || root.algorithm !== ALGORITHM || typeof root.keyId !== "string" || !HASH_PATTERN.test(root.keyId)) {
|
|
10709
|
-
throw new Error("Native review signature identity is invalid");
|
|
10710
|
-
}
|
|
10711
|
-
const hash = payloadHash(root.payloadHash);
|
|
10712
|
-
const signature = canonicalBase64(
|
|
10713
|
-
root.signature,
|
|
10714
|
-
"Native review signature",
|
|
10715
|
-
MAX_SIGNATURE_TEXT,
|
|
10716
|
-
64
|
|
10717
|
-
).toString("base64");
|
|
10718
|
-
return {
|
|
10719
|
-
schema: NATIVE_REVIEW_SIGNATURE_SCHEMA,
|
|
10720
|
-
algorithm: ALGORITHM,
|
|
10721
|
-
keyId: root.keyId,
|
|
10722
|
-
payloadHash: hash,
|
|
10723
|
-
signature
|
|
10724
|
-
};
|
|
10725
|
-
}
|
|
10726
|
-
function parseNativeReviewIdentity(value) {
|
|
10727
|
-
const root = record(value, "Native review identity");
|
|
10728
|
-
exactKeys(root, ["schema", "algorithm", "keyId", "publicKey"], "Native review identity");
|
|
10729
|
-
if (root.schema !== NATIVE_REVIEW_IDENTITY_SCHEMA || root.algorithm !== ALGORITHM || typeof root.keyId !== "string" || !HASH_PATTERN.test(root.keyId)) {
|
|
10730
|
-
throw new Error("Native review identity keyId is invalid");
|
|
10731
|
-
}
|
|
10732
|
-
const publicKey = publicKeyMaterial(root.publicKey);
|
|
10733
|
-
const keyId = sha2562(publicKey.der);
|
|
10734
|
-
if (root.keyId !== keyId) {
|
|
10735
|
-
throw new Error("Native review identity keyId does not match its public key");
|
|
10736
|
-
}
|
|
10737
|
-
return {
|
|
10738
|
-
schema: NATIVE_REVIEW_IDENTITY_SCHEMA,
|
|
10739
|
-
algorithm: ALGORITHM,
|
|
10740
|
-
keyId,
|
|
10741
|
-
publicKey: publicKey.text
|
|
10742
|
-
};
|
|
10743
|
-
}
|
|
10744
|
-
function verifyNativeReviewPayloadHash(options) {
|
|
10745
|
-
const identity = parseNativeReviewIdentity(options.identity);
|
|
10746
|
-
const hash = payloadHash(options.payloadHash);
|
|
10747
|
-
const proof = parseNativeReviewSignature(options.proof);
|
|
10748
|
-
if (proof.payloadHash !== hash) {
|
|
10749
|
-
throw new Error("Native review signature payloadHash does not match the expected payloadHash");
|
|
10750
|
-
}
|
|
10751
|
-
if (proof.keyId !== identity.keyId) {
|
|
10752
|
-
throw new Error("Native review signature keyId does not match the public identity");
|
|
10753
|
-
}
|
|
10754
|
-
const signature = canonicalBase64(
|
|
10755
|
-
proof.signature,
|
|
10756
|
-
"Native review signature",
|
|
10757
|
-
MAX_SIGNATURE_TEXT,
|
|
10758
|
-
64
|
|
10759
|
-
);
|
|
10760
|
-
const publicKey = publicKeyMaterial(identity.publicKey);
|
|
10761
|
-
if (!cryptoVerify(null, signaturePayload(hash), publicKey.key, signature)) {
|
|
10762
|
-
throw new Error("Native review signature is invalid");
|
|
10763
|
-
}
|
|
10764
|
-
return proof;
|
|
10765
|
-
}
|
|
10766
|
-
|
|
10767
|
-
// domains/comet-native/native-controller-trust.ts
|
|
10768
|
-
var NATIVE_CONTROLLER_TRUST_STORE_SCHEMA = "comet.native.controller-trust-store.v1";
|
|
10769
|
-
var NATIVE_CONTROLLER_TRUST_STORE_TEST_ENV = "COMET_NATIVE_CONTROLLER_TRUST_STORE_TEST_PATH";
|
|
10770
|
-
var PROJECT_ROOT_HASH_TAG = "comet.native.controller-project-root.v1";
|
|
10771
|
-
var MAX_STORE_BYTES = 256 * 1024;
|
|
10772
|
-
var HASH_PATTERN2 = /^[a-f0-9]{64}$/u;
|
|
10773
|
-
var CHANGE_NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
10774
|
-
function record2(value, label) {
|
|
10775
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
10776
|
-
throw new Error(`${label} must be an object`);
|
|
10777
|
-
}
|
|
10778
|
-
return value;
|
|
10779
|
-
}
|
|
10780
|
-
function exactKeys2(value, keys, label) {
|
|
10781
|
-
const actual = Object.keys(value).sort();
|
|
10782
|
-
const expected = [...keys].sort();
|
|
10783
|
-
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
10784
|
-
throw new Error(`${label} fields are invalid`);
|
|
10785
|
-
}
|
|
10786
|
-
}
|
|
10787
|
-
function isInside4(parent, target) {
|
|
10788
|
-
const relative = path15.relative(parent, target);
|
|
10789
|
-
return relative === "" || !path15.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path15.sep}`);
|
|
10790
|
-
}
|
|
10791
|
-
function normalizedPhysicalRoot(root) {
|
|
10792
|
-
const normalized2 = path15.normalize(root).replaceAll("\\", "/");
|
|
10793
|
-
return process.platform === "win32" ? normalized2.toLowerCase() : normalized2;
|
|
10794
|
-
}
|
|
10795
|
-
async function nativeControllerProjectRootHash(projectRoot) {
|
|
10796
|
-
return canonicalHash(
|
|
10797
|
-
PROJECT_ROOT_HASH_TAG,
|
|
10798
|
-
normalizedPhysicalRoot(await fs11.realpath(projectRoot))
|
|
10799
|
-
);
|
|
10800
|
-
}
|
|
10801
|
-
function parseNativeControllerTrustStore(value) {
|
|
10802
|
-
const root = record2(value, "Native controller trust store");
|
|
10803
|
-
exactKeys2(root, ["schema", "projects"], "Native controller trust store");
|
|
10804
|
-
if (root.schema !== NATIVE_CONTROLLER_TRUST_STORE_SCHEMA || !Array.isArray(root.projects) || root.projects.length === 0 || root.projects.length > 1024) {
|
|
10805
|
-
throw new Error("Native controller trust store is invalid");
|
|
10806
|
-
}
|
|
10807
|
-
const projects = root.projects.map((value2, index) => {
|
|
10808
|
-
const project = record2(value2, `Native controller trust project ${index}`);
|
|
10809
|
-
exactKeys2(
|
|
10810
|
-
project,
|
|
10811
|
-
["projectRootHash", "controllerIdentity", "legacyChanges"],
|
|
10812
|
-
`Native controller trust project ${index}`
|
|
10813
|
-
);
|
|
10814
|
-
if (typeof project.projectRootHash !== "string" || !HASH_PATTERN2.test(project.projectRootHash) || !Array.isArray(project.legacyChanges)) {
|
|
10815
|
-
throw new Error(`Native controller trust project ${index} is invalid`);
|
|
10816
|
-
}
|
|
10817
|
-
const legacyChanges = project.legacyChanges.map((change) => {
|
|
10818
|
-
if (typeof change !== "string" || !CHANGE_NAME_PATTERN.test(change)) {
|
|
10819
|
-
throw new Error(`Native controller trust project ${index} legacy change is invalid`);
|
|
10820
|
-
}
|
|
10821
|
-
return change;
|
|
10822
|
-
});
|
|
10823
|
-
if (JSON.stringify(legacyChanges) !== JSON.stringify(
|
|
10824
|
-
[...new Set(legacyChanges)].sort((left, right) => left.localeCompare(right, "en"))
|
|
10825
|
-
)) {
|
|
10826
|
-
throw new Error(`Native controller trust project ${index} legacy changes must be sorted`);
|
|
10827
|
-
}
|
|
10828
|
-
return {
|
|
10829
|
-
projectRootHash: project.projectRootHash,
|
|
10830
|
-
controllerIdentity: parseNativeReviewIdentity(project.controllerIdentity),
|
|
10831
|
-
legacyChanges
|
|
10832
|
-
};
|
|
10833
|
-
});
|
|
10834
|
-
if (JSON.stringify(projects.map((project) => project.projectRootHash)) !== JSON.stringify(
|
|
10835
|
-
[...new Set(projects.map((project) => project.projectRootHash))].sort(
|
|
10836
|
-
(left, right) => left.localeCompare(right, "en")
|
|
10837
|
-
)
|
|
10838
|
-
)) {
|
|
10839
|
-
throw new Error("Native controller trust projects must be sorted and unique");
|
|
10840
|
-
}
|
|
10841
|
-
return { schema: NATIVE_CONTROLLER_TRUST_STORE_SCHEMA, projects };
|
|
10842
|
-
}
|
|
10843
|
-
function nativeControllerTrustStorePath() {
|
|
10844
|
-
const testPath = process.env.NODE_ENV === "test" ? process.env[NATIVE_CONTROLLER_TRUST_STORE_TEST_ENV] : void 0;
|
|
10845
|
-
return path15.resolve(
|
|
10846
|
-
testPath ?? path15.join(os2.homedir(), ".comet", "native-controller-trust.json")
|
|
10847
|
-
);
|
|
10848
|
-
}
|
|
10849
|
-
async function readNativeControllerTrustProject(projectRoot) {
|
|
10850
|
-
const storePath = nativeControllerTrustStorePath();
|
|
10851
|
-
let physicalProjectRoot;
|
|
10852
|
-
try {
|
|
10853
|
-
physicalProjectRoot = await fs11.realpath(projectRoot);
|
|
10854
|
-
} catch (error) {
|
|
10855
|
-
throw new Error("Native project root is unavailable for controller trust", { cause: error });
|
|
10856
|
-
}
|
|
10857
|
-
let trustedIdentity;
|
|
10858
|
-
try {
|
|
10859
|
-
trustedIdentity = await assertTrustedReadonlyFile({ file: storePath });
|
|
10860
|
-
} catch (error) {
|
|
10861
|
-
if (error.code === "ENOENT") return null;
|
|
10862
|
-
throw new Error("Native controller trust store is not host-isolated read-only", {
|
|
10863
|
-
cause: error
|
|
10864
|
-
});
|
|
10865
|
-
}
|
|
10866
|
-
let result2;
|
|
10867
|
-
try {
|
|
10868
|
-
result2 = await readFileRaceSafe(storePath, MAX_STORE_BYTES, {
|
|
10869
|
-
label: "Native controller trust store",
|
|
10870
|
-
verify: (_checkpoint, context) => {
|
|
10871
|
-
if (isInside4(physicalProjectRoot, context.realPath)) {
|
|
10872
|
-
throw new Error("Native controller trust store must resolve outside the project");
|
|
10873
|
-
}
|
|
10874
|
-
}
|
|
10875
|
-
});
|
|
10876
|
-
} catch (error) {
|
|
10877
|
-
if (error.code === "ENOENT") return null;
|
|
10878
|
-
throw error;
|
|
10879
|
-
}
|
|
10880
|
-
try {
|
|
10881
|
-
await assertTrustedReadonlyFile({
|
|
10882
|
-
file: storePath,
|
|
10883
|
-
previous: trustedIdentity
|
|
10884
|
-
});
|
|
10885
|
-
} catch (error) {
|
|
10886
|
-
throw new Error("Native controller trust store isolation changed while reading", {
|
|
10887
|
-
cause: error
|
|
10888
|
-
});
|
|
10889
|
-
}
|
|
10890
|
-
let parsed;
|
|
10891
|
-
try {
|
|
10892
|
-
parsed = parseNativeControllerTrustStore(JSON.parse(result2.bytes.toString("utf8")));
|
|
10893
|
-
} catch (error) {
|
|
10894
|
-
throw new Error("Native controller trust store is not valid canonical JSON", {
|
|
10895
|
-
cause: error
|
|
10896
|
-
});
|
|
10897
|
-
}
|
|
10898
|
-
const projectRootHash = await nativeControllerProjectRootHash(projectRoot);
|
|
10899
|
-
return parsed.projects.find((project) => project.projectRootHash === projectRootHash) ?? null;
|
|
10900
|
-
}
|
|
10901
|
-
|
|
10902
|
-
// domains/comet-native/native-creation-authorization.ts
|
|
10903
|
-
var NATIVE_CREATION_AUTHORIZATION_SCHEMA = "comet.native.creation-authorization.v1";
|
|
10904
|
-
var HASH_PATTERN3 = /^[a-f0-9]{64}$/u;
|
|
10905
|
-
var CHANGE_NAME_PATTERN2 = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
10906
|
-
function record3(value, label) {
|
|
10907
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
10908
|
-
throw new Error(`${label} must be an object`);
|
|
10909
|
-
}
|
|
10910
|
-
return value;
|
|
10911
|
-
}
|
|
10912
|
-
function exactKeys3(value, expected, label) {
|
|
10913
|
-
const actual = Object.keys(value).sort();
|
|
10914
|
-
const canonical = [...expected].sort();
|
|
10915
|
-
if (JSON.stringify(actual) !== JSON.stringify(canonical)) {
|
|
10916
|
-
throw new Error(`${label} fields are invalid`);
|
|
10917
|
-
}
|
|
10918
|
-
}
|
|
10919
|
-
function parseNativeCreationAuthorization(value) {
|
|
10920
|
-
const root = record3(value, "Native creation authorization");
|
|
10921
|
-
exactKeys3(
|
|
10922
|
-
root,
|
|
10923
|
-
[
|
|
10924
|
-
"schema",
|
|
10925
|
-
"controllerKeyId",
|
|
10926
|
-
"projectRootHash",
|
|
10927
|
-
"policyHash",
|
|
10928
|
-
"protocol",
|
|
10929
|
-
"change",
|
|
10930
|
-
"issuedAt",
|
|
10931
|
-
"authorizationHash",
|
|
10932
|
-
"controllerSignature"
|
|
10933
|
-
],
|
|
10934
|
-
"Native creation authorization"
|
|
10935
|
-
);
|
|
10936
|
-
if (root.schema !== NATIVE_CREATION_AUTHORIZATION_SCHEMA || typeof root.controllerKeyId !== "string" || !HASH_PATTERN3.test(root.controllerKeyId) || typeof root.projectRootHash !== "string" || !HASH_PATTERN3.test(root.projectRootHash) || typeof root.policyHash !== "string" || !HASH_PATTERN3.test(root.policyHash) || root.protocol !== "signed-v2" || typeof root.change !== "string" || !CHANGE_NAME_PATTERN2.test(root.change) || typeof root.issuedAt !== "string" || Number.isNaN(Date.parse(root.issuedAt)) || typeof root.authorizationHash !== "string" || !HASH_PATTERN3.test(root.authorizationHash)) {
|
|
10937
|
-
throw new Error("Native creation authorization is invalid");
|
|
10938
|
-
}
|
|
10939
|
-
const content = {
|
|
10940
|
-
schema: NATIVE_CREATION_AUTHORIZATION_SCHEMA,
|
|
10941
|
-
controllerKeyId: root.controllerKeyId,
|
|
10942
|
-
projectRootHash: root.projectRootHash,
|
|
10943
|
-
policyHash: root.policyHash,
|
|
10944
|
-
protocol: "signed-v2",
|
|
10945
|
-
change: root.change,
|
|
10946
|
-
issuedAt: root.issuedAt
|
|
10947
|
-
};
|
|
10948
|
-
const authorizationHash = canonicalHash(NATIVE_CREATION_AUTHORIZATION_SCHEMA, content);
|
|
10949
|
-
if (authorizationHash !== root.authorizationHash) {
|
|
10950
|
-
throw new Error("Native creation authorization hash mismatch");
|
|
10951
|
-
}
|
|
10952
|
-
const controllerSignature = parseNativeReviewSignature(root.controllerSignature);
|
|
10953
|
-
if (controllerSignature.keyId !== root.controllerKeyId || controllerSignature.payloadHash !== authorizationHash) {
|
|
10954
|
-
throw new Error("Native creation authorization signature binding is invalid");
|
|
10955
|
-
}
|
|
10956
|
-
return { ...content, authorizationHash, controllerSignature };
|
|
10957
|
-
}
|
|
10958
|
-
async function verifyNativeCreationAuthorization(options) {
|
|
10959
|
-
const controllerTrust = await readNativeControllerTrustProject(options.paths.projectRoot);
|
|
10960
|
-
if (!controllerTrust) {
|
|
10961
|
-
throw new Error("Native project has no controller-owned trust root");
|
|
10962
|
-
}
|
|
10963
|
-
const authorization = parseNativeCreationAuthorization(options.authorization);
|
|
10964
|
-
const projectRootHash = await nativeControllerProjectRootHash(options.paths.projectRoot);
|
|
10965
|
-
if (authorization.controllerKeyId !== controllerTrust.controllerIdentity.keyId || authorization.projectRootHash !== projectRootHash || authorization.policyHash !== options.policyHash || authorization.change !== options.change) {
|
|
10966
|
-
throw new Error("Native creation authorization does not match the trusted project/change");
|
|
10967
|
-
}
|
|
10968
|
-
verifyNativeReviewPayloadHash({
|
|
10969
|
-
identity: controllerTrust.controllerIdentity,
|
|
10970
|
-
payloadHash: authorization.authorizationHash,
|
|
10971
|
-
proof: authorization.controllerSignature
|
|
10972
|
-
});
|
|
10973
|
-
return authorization;
|
|
10974
|
-
}
|
|
10975
|
-
|
|
10976
10453
|
// domains/comet-native/native-config.ts
|
|
10977
10454
|
init_project_config();
|
|
10978
10455
|
init_project_config_reader();
|
|
@@ -10994,13 +10471,13 @@ var nativeLockCoordinator = new AsyncLocalStorage();
|
|
|
10994
10471
|
import { TextDecoder as TextDecoder4 } from "util";
|
|
10995
10472
|
|
|
10996
10473
|
// domains/comet-native/native-protected-file.ts
|
|
10997
|
-
import { createHash as
|
|
10998
|
-
import { constants as
|
|
10999
|
-
import
|
|
10474
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
10475
|
+
import { constants as fsConstants2, promises as fs10 } from "node:fs";
|
|
10476
|
+
import path14 from "node:path";
|
|
11000
10477
|
import { TextDecoder as TextDecoder3 } from "node:util";
|
|
11001
|
-
function
|
|
11002
|
-
const relative =
|
|
11003
|
-
return relative === "" || !
|
|
10478
|
+
function isInside4(parent, target) {
|
|
10479
|
+
const relative = path14.relative(parent, target);
|
|
10480
|
+
return relative === "" || !path14.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path14.sep}`);
|
|
11004
10481
|
}
|
|
11005
10482
|
function positiveLimit2(value) {
|
|
11006
10483
|
if (!Number.isSafeInteger(value) || value < 1) {
|
|
@@ -11037,31 +10514,31 @@ function sameFileIdentity3(expected, actual) {
|
|
|
11037
10514
|
) && expected.birthtimeMs === actual.birthtimeMs && expected.ctimeMs === actual.ctimeMs && expected.mtimeMs === actual.mtimeMs && expected.size === actual.size;
|
|
11038
10515
|
}
|
|
11039
10516
|
async function captureDirectoryIdentity2(directory, label) {
|
|
11040
|
-
const stat = await
|
|
10517
|
+
const stat = await fs10.lstat(directory);
|
|
11041
10518
|
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
11042
10519
|
throw new Error(`${label} parent must be a real directory: ${directory}`);
|
|
11043
10520
|
}
|
|
11044
10521
|
return {
|
|
11045
10522
|
path: directory,
|
|
11046
|
-
realPath: await
|
|
10523
|
+
realPath: await fs10.realpath(directory),
|
|
11047
10524
|
dev: stat.dev,
|
|
11048
10525
|
ino: stat.ino,
|
|
11049
10526
|
birthtimeMs: stat.birthtimeMs
|
|
11050
10527
|
};
|
|
11051
10528
|
}
|
|
11052
10529
|
async function captureDirectoryChain2(root, directory, label) {
|
|
11053
|
-
const lexicalRoot =
|
|
11054
|
-
const lexicalDirectory =
|
|
11055
|
-
if (!
|
|
10530
|
+
const lexicalRoot = path14.resolve(root);
|
|
10531
|
+
const lexicalDirectory = path14.resolve(directory);
|
|
10532
|
+
if (!isInside4(lexicalRoot, lexicalDirectory)) {
|
|
11056
10533
|
throw new Error(`${label} is outside its managed root`);
|
|
11057
10534
|
}
|
|
11058
10535
|
const chain = [await captureDirectoryIdentity2(lexicalRoot, label)];
|
|
11059
10536
|
let cursor = lexicalRoot;
|
|
11060
|
-
for (const segment of
|
|
10537
|
+
for (const segment of path14.relative(lexicalRoot, lexicalDirectory).split(path14.sep).filter(Boolean)) {
|
|
11061
10538
|
await verifyDirectoryChain3(chain, label);
|
|
11062
|
-
cursor =
|
|
10539
|
+
cursor = path14.join(cursor, segment);
|
|
11063
10540
|
const identity = await captureDirectoryIdentity2(cursor, label);
|
|
11064
|
-
if (!
|
|
10541
|
+
if (!isInside4(chain[0].realPath, identity.realPath)) {
|
|
11065
10542
|
throw new Error(`${label} parent resolves outside its managed root: ${cursor}`);
|
|
11066
10543
|
}
|
|
11067
10544
|
chain.push(identity);
|
|
@@ -11071,8 +10548,8 @@ async function captureDirectoryChain2(root, directory, label) {
|
|
|
11071
10548
|
}
|
|
11072
10549
|
async function verifyDirectoryChain3(chain, label) {
|
|
11073
10550
|
for (const identity of chain) {
|
|
11074
|
-
const stat = await
|
|
11075
|
-
if (!stat.isDirectory() || stat.isSymbolicLink() || !sameDirectoryIdentity3(identity, stat) || await
|
|
10551
|
+
const stat = await fs10.lstat(identity.path);
|
|
10552
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || !sameDirectoryIdentity3(identity, stat) || await fs10.realpath(identity.path) !== identity.realPath) {
|
|
11076
10553
|
throw new Error(`${label} parent changed during I/O: ${identity.path}`);
|
|
11077
10554
|
}
|
|
11078
10555
|
}
|
|
@@ -11093,36 +10570,36 @@ async function readHandleBounded(handle, maxBytes, label) {
|
|
|
11093
10570
|
}
|
|
11094
10571
|
async function readNativeProtectedFile(options) {
|
|
11095
10572
|
const maxBytes = positiveLimit2(options.maxBytes);
|
|
11096
|
-
const file =
|
|
11097
|
-
const chain = await captureDirectoryChain2(options.root,
|
|
10573
|
+
const file = path14.resolve(options.file);
|
|
10574
|
+
const chain = await captureDirectoryChain2(options.root, path14.dirname(file), options.label);
|
|
11098
10575
|
const forbidden = await Promise.all(
|
|
11099
10576
|
(options.forbiddenRoots ?? []).map(
|
|
11100
|
-
(root) => captureDirectoryIdentity2(
|
|
10577
|
+
(root) => captureDirectoryIdentity2(path14.resolve(root), options.label)
|
|
11101
10578
|
)
|
|
11102
10579
|
);
|
|
11103
10580
|
await options.hooks?.afterParentChainCaptured?.();
|
|
11104
10581
|
await verifyDirectoryChain3(chain, options.label);
|
|
11105
|
-
const before = await
|
|
10582
|
+
const before = await fs10.lstat(file);
|
|
11106
10583
|
if (!before.isFile() || before.isSymbolicLink()) {
|
|
11107
10584
|
throw new Error(`${options.label} must be a regular file`);
|
|
11108
10585
|
}
|
|
11109
10586
|
if (before.size > maxBytes) throw new Error(`${options.label} exceeds ${maxBytes} bytes`);
|
|
11110
10587
|
const beforeIdentity = asFileIdentity(before);
|
|
11111
|
-
const beforeRealPath = await
|
|
11112
|
-
if (!
|
|
10588
|
+
const beforeRealPath = await fs10.realpath(file);
|
|
10589
|
+
if (!isInside4(chain[0].realPath, beforeRealPath)) {
|
|
11113
10590
|
throw new Error(`${options.label} resolves outside its managed root`);
|
|
11114
10591
|
}
|
|
11115
|
-
if (forbidden.some((identity) =>
|
|
10592
|
+
if (forbidden.some((identity) => isInside4(identity.realPath, beforeRealPath))) {
|
|
11116
10593
|
throw new Error(`${options.label} resolves inside an excluded root`);
|
|
11117
10594
|
}
|
|
11118
|
-
const flags = process.platform === "win32" ?
|
|
11119
|
-
const handle = await
|
|
10595
|
+
const flags = process.platform === "win32" ? fsConstants2.O_RDONLY : fsConstants2.O_RDONLY | fsConstants2.O_NOFOLLOW | fsConstants2.O_NONBLOCK;
|
|
10596
|
+
const handle = await fs10.open(file, flags);
|
|
11120
10597
|
try {
|
|
11121
10598
|
const opened = await handle.stat();
|
|
11122
10599
|
await options.hooks?.afterOpen?.();
|
|
11123
10600
|
const [pathAfterOpen, realPathAfterOpen] = await Promise.all([
|
|
11124
|
-
|
|
11125
|
-
|
|
10601
|
+
fs10.lstat(file),
|
|
10602
|
+
fs10.realpath(file)
|
|
11126
10603
|
]);
|
|
11127
10604
|
await verifyDirectoryChain3(chain, options.label);
|
|
11128
10605
|
await verifyDirectoryChain3(forbidden, options.label);
|
|
@@ -11134,8 +10611,8 @@ async function readNativeProtectedFile(options) {
|
|
|
11134
10611
|
await options.hooks?.beforeFinalCheck?.();
|
|
11135
10612
|
const [afterHandle, afterPath, afterRealPath] = await Promise.all([
|
|
11136
10613
|
handle.stat(),
|
|
11137
|
-
|
|
11138
|
-
|
|
10614
|
+
fs10.lstat(file),
|
|
10615
|
+
fs10.realpath(file)
|
|
11139
10616
|
]);
|
|
11140
10617
|
await verifyDirectoryChain3(chain, options.label);
|
|
11141
10618
|
await verifyDirectoryChain3(forbidden, options.label);
|
|
@@ -11144,7 +10621,7 @@ async function readNativeProtectedFile(options) {
|
|
|
11144
10621
|
}
|
|
11145
10622
|
return {
|
|
11146
10623
|
bytes,
|
|
11147
|
-
hash:
|
|
10624
|
+
hash: createHash3("sha256").update(bytes).digest("hex"),
|
|
11148
10625
|
size: bytes.length
|
|
11149
10626
|
};
|
|
11150
10627
|
} finally {
|
|
@@ -11169,104 +10646,13 @@ var NATIVE_TRANSACTION_EVENT_MAX_BYTES = 16 * 1024;
|
|
|
11169
10646
|
var NATIVE_LEGACY_TRANSACTION_FILE_MAX_BYTES = 64 * 1024 * 1024;
|
|
11170
10647
|
var UTF8_DECODER = new TextDecoder4("utf-8", { fatal: true });
|
|
11171
10648
|
|
|
11172
|
-
// domains/comet-native/native-review-trust.ts
|
|
11173
|
-
var NATIVE_REVIEW_TRUST_POLICY_SCHEMA = "comet.native.review-trust-policy.v2";
|
|
11174
|
-
var POLICY_HASH_TAG = NATIVE_REVIEW_TRUST_POLICY_SCHEMA;
|
|
11175
|
-
var MAX_POLICY_BYTES = 64 * 1024;
|
|
11176
|
-
var HASH_PATTERN4 = /^[a-f0-9]{64}$/u;
|
|
11177
|
-
function record4(value, label) {
|
|
11178
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
11179
|
-
throw new Error(`${label} must be an object`);
|
|
11180
|
-
}
|
|
11181
|
-
return value;
|
|
11182
|
-
}
|
|
11183
|
-
function exactKeys4(value, expected, label) {
|
|
11184
|
-
const actual = Object.keys(value).sort();
|
|
11185
|
-
const canonical = [...expected].sort();
|
|
11186
|
-
if (JSON.stringify(actual) !== JSON.stringify(canonical)) {
|
|
11187
|
-
throw new Error(`${label} fields are invalid`);
|
|
11188
|
-
}
|
|
11189
|
-
}
|
|
11190
|
-
function identities(value, label) {
|
|
11191
|
-
if (!Array.isArray(value) || value.length === 0 || value.length > 64) {
|
|
11192
|
-
throw new Error(`${label} must be a bounded non-empty array`);
|
|
11193
|
-
}
|
|
11194
|
-
const parsed = value.map(parseNativeReviewIdentity).sort((left, right) => left.keyId.localeCompare(right.keyId, "en"));
|
|
11195
|
-
if (new Set(parsed.map((identity) => identity.keyId)).size !== parsed.length || JSON.stringify(value) !== JSON.stringify(parsed)) {
|
|
11196
|
-
throw new Error(`${label} must be sorted and unique`);
|
|
11197
|
-
}
|
|
11198
|
-
return parsed;
|
|
11199
|
-
}
|
|
11200
|
-
function parseNativeReviewTrustPolicy(value) {
|
|
11201
|
-
const root = record4(value, "Native review trust policy");
|
|
11202
|
-
exactKeys4(
|
|
11203
|
-
root,
|
|
11204
|
-
[
|
|
11205
|
-
"schema",
|
|
11206
|
-
"controllerKeyId",
|
|
11207
|
-
"implementationKeyId",
|
|
11208
|
-
"trustedReviewers",
|
|
11209
|
-
"trustedWaiverSigners",
|
|
11210
|
-
"policyHash",
|
|
11211
|
-
"controllerSignature"
|
|
11212
|
-
],
|
|
11213
|
-
"Native review trust policy"
|
|
11214
|
-
);
|
|
11215
|
-
if (root.schema !== NATIVE_REVIEW_TRUST_POLICY_SCHEMA || typeof root.controllerKeyId !== "string" || !HASH_PATTERN4.test(root.controllerKeyId) || typeof root.implementationKeyId !== "string" || !HASH_PATTERN4.test(root.implementationKeyId) || typeof root.policyHash !== "string" || !HASH_PATTERN4.test(root.policyHash)) {
|
|
11216
|
-
throw new Error("Native review trust policy identity or hash is invalid");
|
|
11217
|
-
}
|
|
11218
|
-
const trustedReviewers = identities(root.trustedReviewers, "Native trusted reviewers");
|
|
11219
|
-
const trustedWaiverSigners = identities(
|
|
11220
|
-
root.trustedWaiverSigners,
|
|
11221
|
-
"Native trusted waiver signers"
|
|
11222
|
-
);
|
|
11223
|
-
if (trustedReviewers.some((identity) => identity.keyId === root.implementationKeyId) || trustedWaiverSigners.some((identity) => identity.keyId === root.implementationKeyId) || (/* @__PURE__ */ new Set([
|
|
11224
|
-
root.controllerKeyId,
|
|
11225
|
-
root.implementationKeyId,
|
|
11226
|
-
...trustedReviewers.map((identity) => identity.keyId),
|
|
11227
|
-
...trustedWaiverSigners.map((identity) => identity.keyId)
|
|
11228
|
-
])).size !== 2 + trustedReviewers.length + trustedWaiverSigners.length) {
|
|
11229
|
-
throw new Error(
|
|
11230
|
-
"Native controller, implementation, reviewer, and waiver signer identities must be globally distinct"
|
|
11231
|
-
);
|
|
11232
|
-
}
|
|
11233
|
-
const content = {
|
|
11234
|
-
schema: NATIVE_REVIEW_TRUST_POLICY_SCHEMA,
|
|
11235
|
-
controllerKeyId: root.controllerKeyId,
|
|
11236
|
-
implementationKeyId: root.implementationKeyId,
|
|
11237
|
-
trustedReviewers,
|
|
11238
|
-
trustedWaiverSigners
|
|
11239
|
-
};
|
|
11240
|
-
const policyHash = canonicalHash(POLICY_HASH_TAG, content);
|
|
11241
|
-
if (policyHash !== root.policyHash) {
|
|
11242
|
-
throw new Error("Native review trust policy hash mismatch");
|
|
11243
|
-
}
|
|
11244
|
-
const controllerSignature = parseNativeReviewSignature(root.controllerSignature);
|
|
11245
|
-
if (controllerSignature.keyId !== root.controllerKeyId || controllerSignature.payloadHash !== policyHash) {
|
|
11246
|
-
throw new Error("Native review trust policy controller signature binding is invalid");
|
|
11247
|
-
}
|
|
11248
|
-
return { ...content, policyHash, controllerSignature };
|
|
11249
|
-
}
|
|
11250
|
-
function verifyNativeReviewTrustPolicy(value, controllerIdentity) {
|
|
11251
|
-
const policy = parseNativeReviewTrustPolicy(value);
|
|
11252
|
-
if (policy.controllerKeyId !== controllerIdentity.keyId) {
|
|
11253
|
-
throw new Error("Native review trust policy controller is not host-trusted");
|
|
11254
|
-
}
|
|
11255
|
-
verifyNativeReviewPayloadHash({
|
|
11256
|
-
identity: controllerIdentity,
|
|
11257
|
-
payloadHash: policy.policyHash,
|
|
11258
|
-
proof: policy.controllerSignature
|
|
11259
|
-
});
|
|
11260
|
-
return policy;
|
|
11261
|
-
}
|
|
11262
|
-
|
|
11263
10649
|
// domains/comet-native/native-snapshot.ts
|
|
11264
|
-
import
|
|
10650
|
+
import path15 from "path";
|
|
11265
10651
|
|
|
11266
10652
|
// domains/comet-native/native-hash.ts
|
|
11267
|
-
import { createHash as
|
|
10653
|
+
import { createHash as createHash4 } from "crypto";
|
|
11268
10654
|
function sha256Text(content) {
|
|
11269
|
-
return
|
|
10655
|
+
return createHash4("sha256").update(content).digest("hex");
|
|
11270
10656
|
}
|
|
11271
10657
|
|
|
11272
10658
|
// domains/comet-native/native-snapshot.ts
|
|
@@ -11278,11 +10664,10 @@ var DEFAULT_NATIVE_SNAPSHOT_LIMITS = {
|
|
|
11278
10664
|
};
|
|
11279
10665
|
var MAX_RECORDED_OMISSIONS = 1e3;
|
|
11280
10666
|
var NATIVE_SNAPSHOT_MANIFEST_HARD_MAX_BYTES = 8 * 1024 * 1024;
|
|
11281
|
-
var
|
|
10667
|
+
var CHANGE_NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
11282
10668
|
var MANIFEST_KEYS = /* @__PURE__ */ new Set([
|
|
11283
10669
|
"schema",
|
|
11284
10670
|
"origin",
|
|
11285
|
-
"creation",
|
|
11286
10671
|
"capture",
|
|
11287
10672
|
"createdAt",
|
|
11288
10673
|
"complete",
|
|
@@ -11302,14 +10687,6 @@ var LIMIT_KEYS = /* @__PURE__ */ new Set([
|
|
|
11302
10687
|
]);
|
|
11303
10688
|
var POLICY_KEYS = /* @__PURE__ */ new Set(["schema", "include", "exclude", "hash"]);
|
|
11304
10689
|
var CAPTURE_KEYS = /* @__PURE__ */ new Set(["provider", "gitSelection", "physicalSelection", "projection"]);
|
|
11305
|
-
var CREATION_KEYS = /* @__PURE__ */ new Set([
|
|
11306
|
-
"schema",
|
|
11307
|
-
"protocol",
|
|
11308
|
-
"policyHash",
|
|
11309
|
-
"policySnapshotRef",
|
|
11310
|
-
"policySnapshotHash",
|
|
11311
|
-
"authorization"
|
|
11312
|
-
]);
|
|
11313
10690
|
var GIT_PROJECTION_KEYS = /* @__PURE__ */ new Set(["provider", "selection"]);
|
|
11314
10691
|
var GIT_SELECTION_KEYS = /* @__PURE__ */ new Set([
|
|
11315
10692
|
"schema",
|
|
@@ -11363,7 +10740,7 @@ var OMISSION_REASONS = /* @__PURE__ */ new Set([
|
|
|
11363
10740
|
"physical-enumeration-limit",
|
|
11364
10741
|
"physical-selection-changed"
|
|
11365
10742
|
]);
|
|
11366
|
-
var
|
|
10743
|
+
var HASH_PATTERN = /^[a-f0-9]{64}$/u;
|
|
11367
10744
|
var GIT_LIST_STDERR_LIMIT = 64 * 1024;
|
|
11368
10745
|
var GIT_TEXT_STDOUT_LIMIT = 64 * 1024;
|
|
11369
10746
|
var DEFAULT_NATIVE_GIT_SELECTION_LIMITS = {
|
|
@@ -11495,7 +10872,7 @@ function resolveSnapshotPolicy(value) {
|
|
|
11495
10872
|
excludeMatchers: exclude.map(compileNativeSnapshotPattern)
|
|
11496
10873
|
};
|
|
11497
10874
|
}
|
|
11498
|
-
function
|
|
10875
|
+
function record(value, label) {
|
|
11499
10876
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
11500
10877
|
throw new Error(`${label} must be an object`);
|
|
11501
10878
|
}
|
|
@@ -11521,17 +10898,17 @@ function snapshotPath(value, label) {
|
|
|
11521
10898
|
if (typeof value !== "string" || value.length === 0 || value.includes("\\") || value.includes("\0")) {
|
|
11522
10899
|
throw new Error(`${label} must be a normalized project-relative path`);
|
|
11523
10900
|
}
|
|
11524
|
-
const normalized2 =
|
|
11525
|
-
if (normalized2 !== value ||
|
|
10901
|
+
const normalized2 = path15.posix.normalize(value);
|
|
10902
|
+
if (normalized2 !== value || path15.posix.isAbsolute(value) || normalized2 === ".." || normalized2.startsWith("../")) {
|
|
11526
10903
|
throw new Error(`${label} must stay inside the project root`);
|
|
11527
10904
|
}
|
|
11528
10905
|
return value;
|
|
11529
10906
|
}
|
|
11530
10907
|
function parseEntry(value, index) {
|
|
11531
|
-
const entry =
|
|
10908
|
+
const entry = record(value, `Native snapshot entry ${index}`);
|
|
11532
10909
|
rejectUnknown(entry, ENTRY_KEYS, `Native snapshot entry ${index}`);
|
|
11533
10910
|
const entryPath = snapshotPath(entry.path, `Native snapshot entry ${index} path`);
|
|
11534
|
-
if (typeof entry.hash !== "string" || !
|
|
10911
|
+
if (typeof entry.hash !== "string" || !HASH_PATTERN.test(entry.hash)) {
|
|
11535
10912
|
throw new Error(`Native snapshot entry ${index} hash is invalid`);
|
|
11536
10913
|
}
|
|
11537
10914
|
if (entry.type !== "file") throw new Error(`Native snapshot entry ${index} type is invalid`);
|
|
@@ -11543,7 +10920,7 @@ function parseEntry(value, index) {
|
|
|
11543
10920
|
};
|
|
11544
10921
|
}
|
|
11545
10922
|
function parseOmission(value, index) {
|
|
11546
|
-
const omission =
|
|
10923
|
+
const omission = record(value, `Native snapshot omission ${index}`);
|
|
11547
10924
|
rejectUnknown(omission, OMISSION_KEYS, `Native snapshot omission ${index}`);
|
|
11548
10925
|
if (!OMISSION_TYPES.has(omission.type)) {
|
|
11549
10926
|
throw new Error(`Native snapshot omission ${index} type is invalid`);
|
|
@@ -11559,9 +10936,9 @@ function parseOmission(value, index) {
|
|
|
11559
10936
|
};
|
|
11560
10937
|
}
|
|
11561
10938
|
function parseOmissionOverflow(value) {
|
|
11562
|
-
const overflow =
|
|
10939
|
+
const overflow = record(value, "Native snapshot omission overflow");
|
|
11563
10940
|
rejectUnknown(overflow, OMISSION_OVERFLOW_KEYS, "Native snapshot omission overflow");
|
|
11564
|
-
if (typeof overflow.hash !== "string" || !
|
|
10941
|
+
if (typeof overflow.hash !== "string" || !HASH_PATTERN.test(overflow.hash)) {
|
|
11565
10942
|
throw new Error("Native snapshot omission overflow hash is invalid");
|
|
11566
10943
|
}
|
|
11567
10944
|
const expectedRef = `native-snapshot://omitted-overflow/${overflow.hash}`;
|
|
@@ -11575,9 +10952,9 @@ function parseOmissionOverflow(value) {
|
|
|
11575
10952
|
};
|
|
11576
10953
|
}
|
|
11577
10954
|
function parseGitSelectionStreamEvidence(value, label) {
|
|
11578
|
-
const stream =
|
|
10955
|
+
const stream = record(value, label);
|
|
11579
10956
|
rejectUnknown(stream, GIT_SELECTION_STREAM_KEYS, label);
|
|
11580
|
-
if (typeof stream.hash !== "string" || !
|
|
10957
|
+
if (typeof stream.hash !== "string" || !HASH_PATTERN.test(stream.hash)) {
|
|
11581
10958
|
throw new Error(`${label} hash is invalid`);
|
|
11582
10959
|
}
|
|
11583
10960
|
if (typeof stream.overflow !== "boolean") {
|
|
@@ -11601,7 +10978,7 @@ function parseGitSelectionStreamEvidence(value, label) {
|
|
|
11601
10978
|
};
|
|
11602
10979
|
}
|
|
11603
10980
|
function parseGitSelectionEvidence(value) {
|
|
11604
|
-
const selection =
|
|
10981
|
+
const selection = record(value, "Native Git selection evidence");
|
|
11605
10982
|
rejectUnknown(selection, GIT_SELECTION_KEYS, "Native Git selection evidence");
|
|
11606
10983
|
if (selection.schema !== "comet.native.git-selection.v1") {
|
|
11607
10984
|
throw new Error("Native Git selection evidence schema is invalid");
|
|
@@ -11661,9 +11038,9 @@ function parseGitSelectionEvidence(value) {
|
|
|
11661
11038
|
};
|
|
11662
11039
|
}
|
|
11663
11040
|
function parsePhysicalSelectionStreamEvidence(value, label) {
|
|
11664
|
-
const stream =
|
|
11041
|
+
const stream = record(value, label);
|
|
11665
11042
|
rejectUnknown(stream, PHYSICAL_SELECTION_STREAM_KEYS, label);
|
|
11666
|
-
if (typeof stream.hash !== "string" || !
|
|
11043
|
+
if (typeof stream.hash !== "string" || !HASH_PATTERN.test(stream.hash)) {
|
|
11667
11044
|
throw new Error(`${label} hash is invalid`);
|
|
11668
11045
|
}
|
|
11669
11046
|
if (typeof stream.overflow !== "boolean" || typeof stream.unstable !== "boolean") {
|
|
@@ -11690,7 +11067,7 @@ function parsePhysicalSelectionStreamEvidence(value, label) {
|
|
|
11690
11067
|
};
|
|
11691
11068
|
}
|
|
11692
11069
|
function parsePhysicalSelectionEvidence(value) {
|
|
11693
|
-
const selection =
|
|
11070
|
+
const selection = record(value, "Native physical selection evidence");
|
|
11694
11071
|
rejectUnknown(selection, PHYSICAL_SELECTION_KEYS, "Native physical selection evidence");
|
|
11695
11072
|
if (selection.schema !== "comet.native.physical-selection.v1") {
|
|
11696
11073
|
throw new Error("Native physical selection evidence schema is invalid");
|
|
@@ -11723,7 +11100,7 @@ function parsePhysicalSelectionEvidence(value) {
|
|
|
11723
11100
|
};
|
|
11724
11101
|
}
|
|
11725
11102
|
function parseNativeContentSnapshotManifest(value) {
|
|
11726
|
-
const manifest =
|
|
11103
|
+
const manifest = record(value, "Native content snapshot manifest");
|
|
11727
11104
|
rejectUnknown(manifest, MANIFEST_KEYS, "Native content snapshot manifest");
|
|
11728
11105
|
if (manifest.schema !== "comet.native.content-snapshot.v1") {
|
|
11729
11106
|
throw new Error("Unsupported Native content snapshot schema");
|
|
@@ -11731,28 +11108,9 @@ function parseNativeContentSnapshotManifest(value) {
|
|
|
11731
11108
|
if (!SNAPSHOT_ORIGINS.has(manifest.origin)) {
|
|
11732
11109
|
throw new Error("Native content snapshot origin is invalid");
|
|
11733
11110
|
}
|
|
11734
|
-
let creation;
|
|
11735
|
-
if (manifest.creation !== void 0) {
|
|
11736
|
-
const value2 = record5(manifest.creation, "Native change creation binding");
|
|
11737
|
-
rejectUnknown(value2, CREATION_KEYS, "Native change creation binding");
|
|
11738
|
-
if (value2.schema !== "comet.native.change-creation-binding.v1" || value2.protocol !== "signed-v2" || typeof value2.policyHash !== "string" || !HASH_PATTERN5.test(value2.policyHash) || typeof value2.policySnapshotHash !== "string" || !HASH_PATTERN5.test(value2.policySnapshotHash) || typeof value2.policySnapshotRef !== "string" || !/^runtime\/trust\/review-policy-[a-f0-9]{64}\.json$/u.test(value2.policySnapshotRef)) {
|
|
11739
|
-
throw new Error("Native change creation binding is invalid");
|
|
11740
|
-
}
|
|
11741
|
-
creation = {
|
|
11742
|
-
schema: "comet.native.change-creation-binding.v1",
|
|
11743
|
-
protocol: "signed-v2",
|
|
11744
|
-
policyHash: value2.policyHash,
|
|
11745
|
-
policySnapshotRef: value2.policySnapshotRef,
|
|
11746
|
-
policySnapshotHash: value2.policySnapshotHash,
|
|
11747
|
-
authorization: parseNativeCreationAuthorization(value2.authorization)
|
|
11748
|
-
};
|
|
11749
|
-
}
|
|
11750
|
-
if (manifest.origin !== "change-created" && creation !== void 0) {
|
|
11751
|
-
throw new Error("Native change creation binding does not match snapshot origin");
|
|
11752
|
-
}
|
|
11753
11111
|
let capture;
|
|
11754
11112
|
if (manifest.capture !== void 0) {
|
|
11755
|
-
const captureValue =
|
|
11113
|
+
const captureValue = record(manifest.capture, "Native content snapshot capture");
|
|
11756
11114
|
rejectUnknown(captureValue, CAPTURE_KEYS, "Native content snapshot capture");
|
|
11757
11115
|
if (captureValue.provider !== "git" && captureValue.provider !== "physical-tree") {
|
|
11758
11116
|
throw new Error("Native content snapshot capture provider is invalid");
|
|
@@ -11761,7 +11119,7 @@ function parseNativeContentSnapshotManifest(value) {
|
|
|
11761
11119
|
const physicalSelection2 = captureValue.physicalSelection === void 0 ? void 0 : parsePhysicalSelectionEvidence(captureValue.physicalSelection);
|
|
11762
11120
|
let projection = null;
|
|
11763
11121
|
if (captureValue.projection !== void 0) {
|
|
11764
|
-
const projectionValue =
|
|
11122
|
+
const projectionValue = record(captureValue.projection, "Native content snapshot projection");
|
|
11765
11123
|
rejectUnknown(projectionValue, GIT_PROJECTION_KEYS, "Native content snapshot projection");
|
|
11766
11124
|
if (projectionValue.provider !== "git") {
|
|
11767
11125
|
throw new Error("Native content snapshot projection provider is invalid");
|
|
@@ -11798,7 +11156,7 @@ function parseNativeContentSnapshotManifest(value) {
|
|
|
11798
11156
|
if (typeof manifest.complete !== "boolean") {
|
|
11799
11157
|
throw new Error("Native content snapshot complete flag is invalid");
|
|
11800
11158
|
}
|
|
11801
|
-
const limitValue =
|
|
11159
|
+
const limitValue = record(manifest.limits, "Native content snapshot limits");
|
|
11802
11160
|
rejectUnknown(limitValue, LIMIT_KEYS, "Native content snapshot limits");
|
|
11803
11161
|
const limits = {
|
|
11804
11162
|
maxFiles: positiveInteger(limitValue.maxFiles, "Native snapshot maxFiles"),
|
|
@@ -11814,7 +11172,7 @@ function parseNativeContentSnapshotManifest(value) {
|
|
|
11814
11172
|
};
|
|
11815
11173
|
let policy;
|
|
11816
11174
|
if (manifest.policy !== void 0) {
|
|
11817
|
-
const policyValue =
|
|
11175
|
+
const policyValue = record(manifest.policy, "Native snapshot policy");
|
|
11818
11176
|
rejectUnknown(policyValue, POLICY_KEYS, "Native snapshot policy");
|
|
11819
11177
|
if (policyValue.schema !== "comet.native.snapshot-policy.v1") {
|
|
11820
11178
|
throw new Error("Native snapshot policy schema is invalid");
|
|
@@ -11907,7 +11265,6 @@ function parseNativeContentSnapshotManifest(value) {
|
|
|
11907
11265
|
const parsed = {
|
|
11908
11266
|
schema: "comet.native.content-snapshot.v1",
|
|
11909
11267
|
origin: manifest.origin,
|
|
11910
|
-
...creation ? { creation } : {},
|
|
11911
11268
|
...capture ? { capture } : {},
|
|
11912
11269
|
createdAt: manifest.createdAt,
|
|
11913
11270
|
complete: manifest.complete,
|
|
@@ -11924,10 +11281,10 @@ function parseNativeContentSnapshotManifest(value) {
|
|
|
11924
11281
|
return parsed;
|
|
11925
11282
|
}
|
|
11926
11283
|
function nativeBaselineManifestFile(paths, name) {
|
|
11927
|
-
if (!
|
|
11928
|
-
const changeDir =
|
|
11284
|
+
if (!CHANGE_NAME_PATTERN.test(name)) throw new Error(`Invalid Native change name: ${name}`);
|
|
11285
|
+
const changeDir = path15.join(paths.changesDir, name);
|
|
11929
11286
|
if (!isInsidePath(paths.changesDir, changeDir)) throw new Error("Native change path escaped");
|
|
11930
|
-
return
|
|
11287
|
+
return path15.join(changeDir, "runtime", "baseline-manifest.json");
|
|
11931
11288
|
}
|
|
11932
11289
|
async function readNativeBaselineManifest(paths, name) {
|
|
11933
11290
|
const file = nativeBaselineManifestFile(paths, name);
|
|
@@ -12000,7 +11357,7 @@ var PHASES2 = /* @__PURE__ */ new Set(["shape", "build", "verify", "archive"]);
|
|
|
12000
11357
|
var APPROVALS = /* @__PURE__ */ new Set(["implicit", "confirmed"]);
|
|
12001
11358
|
var VERIFY_RESULTS2 = /* @__PURE__ */ new Set(["pending", "pass", "fail"]);
|
|
12002
11359
|
var NATIVE_CHANGE_STATE_FILE = "comet-state.yaml";
|
|
12003
|
-
var
|
|
11360
|
+
var HASH_PATTERN2 = /^[a-f0-9]{64}$/u;
|
|
12004
11361
|
var NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
|
|
12005
11362
|
var CONTENT_ADDRESSED_REF_PATTERN = /^runtime\/evidence\/(scopes|allowances|verifications)\/([a-f0-9]{64})\.json$/u;
|
|
12006
11363
|
var NativeSchemaMigrationRequiredError = class extends Error {
|
|
@@ -12047,7 +11404,7 @@ var NATIVE_BRIEF_TEMPLATE = [
|
|
|
12047
11404
|
"# Verification expectations",
|
|
12048
11405
|
""
|
|
12049
11406
|
].join("\n");
|
|
12050
|
-
function
|
|
11407
|
+
function record2(value, label) {
|
|
12051
11408
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
12052
11409
|
throw new Error(`${label} must be a mapping`);
|
|
12053
11410
|
}
|
|
@@ -12064,12 +11421,12 @@ function assertCapabilityId(value) {
|
|
|
12064
11421
|
if (!NAME_PATTERN.test(value)) throw new Error(`Invalid Native capability id: ${value}`);
|
|
12065
11422
|
}
|
|
12066
11423
|
function assertRelativeRef(value, label) {
|
|
12067
|
-
if (value.length === 0 ||
|
|
11424
|
+
if (value.length === 0 || path16.isAbsolute(value) || /^(?:[A-Za-z]:|~|[\\/])/u.test(value) || value.split(/[\\/]/u).includes("..")) {
|
|
12068
11425
|
throw new Error(`${label} must stay inside the Native change`);
|
|
12069
11426
|
}
|
|
12070
11427
|
}
|
|
12071
11428
|
function parseSpecChange(value, index) {
|
|
12072
|
-
const item =
|
|
11429
|
+
const item = record2(value, `spec_changes[${index}]`);
|
|
12073
11430
|
rejectUnknown2(item, SPEC_CHANGE_KEYS, `spec_changes[${index}]`);
|
|
12074
11431
|
if (typeof item.capability !== "string") throw new Error("spec change capability is required");
|
|
12075
11432
|
assertCapabilityId(item.capability);
|
|
@@ -12088,12 +11445,12 @@ function parseSpecChange(value, index) {
|
|
|
12088
11445
|
throw new Error(`Create spec ${item.capability} requires null base_hash`);
|
|
12089
11446
|
} else if (item.operation === "replace") {
|
|
12090
11447
|
if (!source) throw new Error(`Replace spec ${item.capability} requires source`);
|
|
12091
|
-
if (typeof baseHash !== "string" || !
|
|
11448
|
+
if (typeof baseHash !== "string" || !HASH_PATTERN2.test(baseHash)) {
|
|
12092
11449
|
throw new Error(`Replace spec ${item.capability} requires a SHA-256 base_hash`);
|
|
12093
11450
|
}
|
|
12094
11451
|
} else {
|
|
12095
11452
|
if (source !== void 0) throw new Error(`Remove spec ${item.capability} forbids source`);
|
|
12096
|
-
if (typeof baseHash !== "string" || !
|
|
11453
|
+
if (typeof baseHash !== "string" || !HASH_PATTERN2.test(baseHash)) {
|
|
12097
11454
|
throw new Error(`Remove spec ${item.capability} requires a SHA-256 base_hash`);
|
|
12098
11455
|
}
|
|
12099
11456
|
}
|
|
@@ -12161,7 +11518,7 @@ function parseChangeFields(root, knownKeys) {
|
|
|
12161
11518
|
};
|
|
12162
11519
|
}
|
|
12163
11520
|
function parseLegacyNativeChangeValue(value) {
|
|
12164
|
-
const root =
|
|
11521
|
+
const root = record2(value, NATIVE_CHANGE_STATE_FILE);
|
|
12165
11522
|
if (root.schema !== NATIVE_LEGACY_CHANGE_SCHEMA) {
|
|
12166
11523
|
throw new Error(`Expected ${NATIVE_LEGACY_CHANGE_SCHEMA}`);
|
|
12167
11524
|
}
|
|
@@ -12188,20 +11545,20 @@ function contentAddressedRef(value, label, kind) {
|
|
|
12188
11545
|
}
|
|
12189
11546
|
function approvedContractHash(value) {
|
|
12190
11547
|
if (value === void 0 || value === null) return null;
|
|
12191
|
-
if (typeof value !== "string" || !
|
|
11548
|
+
if (typeof value !== "string" || !HASH_PATTERN2.test(value)) {
|
|
12192
11549
|
throw new Error("Native approved_contract_hash must be null or a SHA-256 hash");
|
|
12193
11550
|
}
|
|
12194
11551
|
return value;
|
|
12195
11552
|
}
|
|
12196
11553
|
function verificationProtocol(value) {
|
|
12197
11554
|
if (value === void 0) return "legacy-v1";
|
|
12198
|
-
if (value !== "legacy-v1"
|
|
12199
|
-
throw new Error("Native verification_protocol must be legacy-v1
|
|
11555
|
+
if (value !== "legacy-v1") {
|
|
11556
|
+
throw new Error("Native verification_protocol must be legacy-v1");
|
|
12200
11557
|
}
|
|
12201
11558
|
return value;
|
|
12202
11559
|
}
|
|
12203
11560
|
function parseV2NativeChangeValue(value) {
|
|
12204
|
-
const root =
|
|
11561
|
+
const root = record2(value, NATIVE_CHANGE_STATE_FILE);
|
|
12205
11562
|
if (root.schema !== NATIVE_V2_CHANGE_SCHEMA) {
|
|
12206
11563
|
throw new Error(`Expected ${NATIVE_V2_CHANGE_SCHEMA}`);
|
|
12207
11564
|
}
|
|
@@ -12220,7 +11577,7 @@ function parseV2NativeChangeValue(value) {
|
|
|
12220
11577
|
};
|
|
12221
11578
|
}
|
|
12222
11579
|
function parseNativeChangeValue(value) {
|
|
12223
|
-
const root =
|
|
11580
|
+
const root = record2(value, NATIVE_CHANGE_STATE_FILE);
|
|
12224
11581
|
if (root.schema !== NATIVE_CHANGE_SCHEMA) {
|
|
12225
11582
|
if (root.schema === NATIVE_LEGACY_CHANGE_SCHEMA || root.schema === NATIVE_V2_CHANGE_SCHEMA) {
|
|
12226
11583
|
const previous = root.schema === NATIVE_LEGACY_CHANGE_SCHEMA ? parseLegacyNativeChangeValue(root) : parseV2NativeChangeValue(root);
|
|
@@ -12274,7 +11631,7 @@ function parseNativeChangeValue(value) {
|
|
|
12274
11631
|
};
|
|
12275
11632
|
}
|
|
12276
11633
|
function inspectNativeChangeValue(value) {
|
|
12277
|
-
const root =
|
|
11634
|
+
const root = record2(value, NATIVE_CHANGE_STATE_FILE);
|
|
12278
11635
|
if (root.schema === NATIVE_LEGACY_CHANGE_SCHEMA) {
|
|
12279
11636
|
const state2 = parseLegacyNativeChangeValue(root);
|
|
12280
11637
|
return {
|
|
@@ -12331,15 +11688,15 @@ function inspectNativeChangeValue(value) {
|
|
|
12331
11688
|
}
|
|
12332
11689
|
function nativeChangeDir(paths, name) {
|
|
12333
11690
|
assertNativeName(name);
|
|
12334
|
-
const target =
|
|
11691
|
+
const target = path16.join(paths.changesDir, name);
|
|
12335
11692
|
if (!isInsidePath(paths.changesDir, target)) throw new Error("Native change path escaped");
|
|
12336
11693
|
return target;
|
|
12337
11694
|
}
|
|
12338
11695
|
async function hasPendingNativeSchemaMigration(paths, name) {
|
|
12339
|
-
const file =
|
|
11696
|
+
const file = path16.join(nativeChangeDir(paths, name), "runtime", "schema-migration.json");
|
|
12340
11697
|
await resolveContainedNativePath(paths.nativeRoot, file);
|
|
12341
11698
|
try {
|
|
12342
|
-
await
|
|
11699
|
+
await fs11.lstat(file);
|
|
12343
11700
|
return true;
|
|
12344
11701
|
} catch (error) {
|
|
12345
11702
|
if (error.code === "ENOENT") return false;
|
|
@@ -12347,8 +11704,8 @@ async function hasPendingNativeSchemaMigration(paths, name) {
|
|
|
12347
11704
|
}
|
|
12348
11705
|
}
|
|
12349
11706
|
var NATIVE_CHANGE_DOCUMENT_MAX_BYTES = 256 * 1024;
|
|
12350
|
-
async function readChangeDocumentFile(file, root =
|
|
12351
|
-
const ref =
|
|
11707
|
+
async function readChangeDocumentFile(file, root = path16.dirname(file)) {
|
|
11708
|
+
const ref = path16.relative(root, file).split(path16.sep).join("/");
|
|
12352
11709
|
const source = await readNativeBoundedTextFile({
|
|
12353
11710
|
root,
|
|
12354
11711
|
ref,
|
|
@@ -12361,7 +11718,7 @@ async function readChangeDocumentFile(file, root = path18.dirname(file)) {
|
|
|
12361
11718
|
return document.toJS();
|
|
12362
11719
|
}
|
|
12363
11720
|
async function inspectNativeChange(paths, name) {
|
|
12364
|
-
const file =
|
|
11721
|
+
const file = path16.join(nativeChangeDir(paths, name), NATIVE_CHANGE_STATE_FILE);
|
|
12365
11722
|
await resolveContainedNativePath(paths.nativeRoot, file);
|
|
12366
11723
|
const inspection = inspectNativeChangeValue(await readChangeDocumentFile(file, paths.nativeRoot));
|
|
12367
11724
|
if (inspection.state && inspection.state.name !== name) {
|
|
@@ -12382,67 +11739,10 @@ async function inspectNativeChange(paths, name) {
|
|
|
12382
11739
|
return inspection;
|
|
12383
11740
|
}
|
|
12384
11741
|
async function assertNativeVerificationProtocolBinding(paths, state) {
|
|
12385
|
-
const controllerTrust = await readNativeControllerTrustProject(paths.projectRoot);
|
|
12386
|
-
const controllerRequiresSigned = controllerTrust !== null && !controllerTrust.legacyChanges.includes(state.name);
|
|
12387
|
-
if (controllerRequiresSigned && state.verification_protocol !== "signed-v2") {
|
|
12388
|
-
throw new Error(
|
|
12389
|
-
`Native verification protocol does not match its creation baseline (controller-backed): expected signed-v2 for ${state.name}`
|
|
12390
|
-
);
|
|
12391
|
-
}
|
|
12392
|
-
if (controllerTrust !== null && controllerTrust.legacyChanges.includes(state.name) && state.verification_protocol !== "legacy-v1") {
|
|
12393
|
-
throw new Error(`Native controller trust marks ${state.name} as legacy-v1`);
|
|
12394
|
-
}
|
|
12395
11742
|
const baseline = await readNativeBaselineManifest(paths, state.name);
|
|
12396
|
-
if (baseline === null)
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
`Native signed-v2 verification protocol has no creation baseline: ${state.name}`
|
|
12400
|
-
);
|
|
12401
|
-
}
|
|
12402
|
-
return;
|
|
12403
|
-
}
|
|
12404
|
-
const expectedProtocol = baseline.creation ? "signed-v2" : "legacy-v1";
|
|
12405
|
-
if (state.verification_protocol !== expectedProtocol) {
|
|
12406
|
-
throw new Error(
|
|
12407
|
-
`Native verification protocol does not match its creation baseline: expected ${expectedProtocol}, got ${state.verification_protocol}`
|
|
12408
|
-
);
|
|
12409
|
-
}
|
|
12410
|
-
if (expectedProtocol === "signed-v2") {
|
|
12411
|
-
if (!controllerTrust) {
|
|
12412
|
-
throw new Error("Native signed-v2 creation has no controller-owned trust root");
|
|
12413
|
-
}
|
|
12414
|
-
const creation = baseline.creation;
|
|
12415
|
-
const changeDir = nativeChangeDir(paths, state.name);
|
|
12416
|
-
const snapshot = await readNativeProtectedTextFile({
|
|
12417
|
-
root: nativeChangeDir(paths, state.name),
|
|
12418
|
-
file: path18.join(changeDir, ...creation.policySnapshotRef.split("/")),
|
|
12419
|
-
maxBytes: 64 * 1024,
|
|
12420
|
-
label: "Native creation-time trust policy snapshot"
|
|
12421
|
-
});
|
|
12422
|
-
if (createHash7("sha256").update(snapshot.text).digest("hex") !== creation.policySnapshotHash) {
|
|
12423
|
-
throw new Error("Native creation-time trust policy snapshot hash mismatch");
|
|
12424
|
-
}
|
|
12425
|
-
let policy;
|
|
12426
|
-
try {
|
|
12427
|
-
policy = JSON.parse(snapshot.text);
|
|
12428
|
-
} catch (error) {
|
|
12429
|
-
throw new Error("Native creation-time trust policy snapshot is invalid JSON", {
|
|
12430
|
-
cause: error
|
|
12431
|
-
});
|
|
12432
|
-
}
|
|
12433
|
-
const verifiedPolicy = verifyNativeReviewTrustPolicy(
|
|
12434
|
-
policy,
|
|
12435
|
-
controllerTrust.controllerIdentity
|
|
12436
|
-
);
|
|
12437
|
-
if (verifiedPolicy.policyHash !== creation.policyHash) {
|
|
12438
|
-
throw new Error("Native creation-time trust policy snapshot does not match its binding");
|
|
12439
|
-
}
|
|
12440
|
-
await verifyNativeCreationAuthorization({
|
|
12441
|
-
paths,
|
|
12442
|
-
policyHash: creation.policyHash,
|
|
12443
|
-
authorization: creation.authorization,
|
|
12444
|
-
change: state.name
|
|
12445
|
-
});
|
|
11743
|
+
if (baseline === null) return;
|
|
11744
|
+
if (state.verification_protocol !== "legacy-v1") {
|
|
11745
|
+
throw new Error(`Native verification protocol is unsupported: ${state.verification_protocol}`);
|
|
12446
11746
|
}
|
|
12447
11747
|
}
|
|
12448
11748
|
async function readNativeChange(paths, name) {
|
|
@@ -12473,14 +11773,14 @@ async function resolveSelectedNativeChange(paths) {
|
|
|
12473
11773
|
|
|
12474
11774
|
// domains/comet-native/native-hook-guard.ts
|
|
12475
11775
|
function isWithin(parent, target) {
|
|
12476
|
-
const relative =
|
|
12477
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
11776
|
+
const relative = path17.relative(parent, target);
|
|
11777
|
+
return relative === "" || !relative.startsWith("..") && !path17.isAbsolute(relative);
|
|
12478
11778
|
}
|
|
12479
11779
|
function requestTargetsAreControlOnly(projectRoot, nativeRoot, request) {
|
|
12480
11780
|
return request.targets.length > 0 && request.targets.every((targetPath) => {
|
|
12481
|
-
const target =
|
|
11781
|
+
const target = path17.resolve(projectRoot, targetPath);
|
|
12482
11782
|
if (!isWithin(projectRoot, target)) return true;
|
|
12483
|
-
const relative =
|
|
11783
|
+
const relative = path17.relative(projectRoot, target).replaceAll("\\", "/");
|
|
12484
11784
|
return relative === ".comet/config.yaml" || isWithin(nativeRoot, target);
|
|
12485
11785
|
});
|
|
12486
11786
|
}
|
|
@@ -12490,7 +11790,7 @@ async function activeNativeContext(projectRoot) {
|
|
|
12490
11790
|
const paths = await nativeProjectPaths(projectRoot, config.native.artifact_root);
|
|
12491
11791
|
let entries;
|
|
12492
11792
|
try {
|
|
12493
|
-
entries = await
|
|
11793
|
+
entries = await fs12.readdir(paths.changesDir, { withFileTypes: true });
|
|
12494
11794
|
} catch (error) {
|
|
12495
11795
|
if (error.code === "ENOENT") return { paths, changes: [] };
|
|
12496
11796
|
throw error;
|
|
@@ -12568,12 +11868,12 @@ async function inspectNativeHookGuard(projectRoot, request, selectedChangeName)
|
|
|
12568
11868
|
let controlTarget = false;
|
|
12569
11869
|
let externalTarget = false;
|
|
12570
11870
|
for (const targetPath of request.targets) {
|
|
12571
|
-
const target =
|
|
11871
|
+
const target = path17.resolve(projectRoot, targetPath);
|
|
12572
11872
|
if (!isWithin(projectRoot, target)) {
|
|
12573
11873
|
externalTarget = true;
|
|
12574
11874
|
continue;
|
|
12575
11875
|
}
|
|
12576
|
-
const relative =
|
|
11876
|
+
const relative = path17.relative(projectRoot, target).replaceAll("\\", "/");
|
|
12577
11877
|
if (relative === ".comet/config.yaml" || isWithin(context.paths.nativeRoot, target)) {
|
|
12578
11878
|
controlTarget = true;
|
|
12579
11879
|
continue;
|
|
@@ -12731,14 +12031,14 @@ function parseArgs(args) {
|
|
|
12731
12031
|
throw new Error(`unsupported Hook platform: ${platformId}`);
|
|
12732
12032
|
}
|
|
12733
12033
|
if (projectRoot?.startsWith("--")) throw new Error("--project-root requires a value");
|
|
12734
|
-
return { platformId, ...projectRoot ? { projectRoot:
|
|
12034
|
+
return { platformId, ...projectRoot ? { projectRoot: path18.resolve(projectRoot) } : {} };
|
|
12735
12035
|
}
|
|
12736
12036
|
async function projectRootFrom(parsed) {
|
|
12737
12037
|
if (parsed.projectRoot) return parsed.projectRoot;
|
|
12738
12038
|
const discovered = await discoverNativeProject(process.cwd());
|
|
12739
12039
|
for (const marker of [[".comet", "config.yaml"], [".git"]]) {
|
|
12740
12040
|
try {
|
|
12741
|
-
await
|
|
12041
|
+
await fs13.lstat(path18.join(discovered, ...marker));
|
|
12742
12042
|
return discovered;
|
|
12743
12043
|
} catch (error) {
|
|
12744
12044
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -12747,7 +12047,7 @@ async function projectRootFrom(parsed) {
|
|
|
12747
12047
|
const classic = await discoverClassicProject(process.cwd());
|
|
12748
12048
|
const layout = await assertClassicLayoutReadable(classic);
|
|
12749
12049
|
try {
|
|
12750
|
-
await
|
|
12050
|
+
await fs13.lstat(layout.changesDir);
|
|
12751
12051
|
return classic;
|
|
12752
12052
|
} catch (error) {
|
|
12753
12053
|
if (error.code !== "ENOENT") throw error;
|