deadbyte-mcp 0.15.71 → 0.15.74
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/MANIFEST.SHA256 +81 -28
- package/PROVENANCE.json +56 -16
- package/README.txt +24 -18
- package/RELEASE.json +67 -18
- package/SBOM.cdx.json +14 -2
- package/TEST-MATRIX.json +44 -2
- package/bin/deadbyte-owner-token-r193.exe +0 -0
- package/bridge/package.json +1 -1
- package/controller/deadbyte-process-policy.json +4 -4
- package/docs/R184-package-lock.json +2 -2
- package/docs/R192-LIVE-LOG-HARDENING.txt +39 -0
- package/native/deadbyte-owner-token-r193.cpp +156 -0
- package/package.json +2 -2
- package/scripts/gate-windows-r193.ps1 +108 -0
- package/scripts/gate-windows-r194.ps1 +112 -0
- package/scripts/npm-interactive-r194.mjs +13 -0
- package/scripts/npm-publication-r65.mjs +64 -4
- package/scripts/npm-release-r48.mjs +58 -11
- package/scripts/npm-release-readiness-r193.mjs +80 -0
- package/scripts/npm-release-readiness-r194.mjs +80 -0
- package/scripts/r188-owner-uac-review.ps1 +91 -0
- package/scripts/r188-uac-review-preview.mjs +65 -0
- package/scripts/r192-focused.mjs +10 -0
- package/scripts/r192-release-tests.mjs +8 -0
- package/scripts/r193-compile-token.ps1 +22 -0
- package/scripts/r193-evidence-relocate.ps1 +12 -0
- package/scripts/r193-focused-gate.mjs +20 -0
- package/scripts/r193-import-r188-scripts.ps1 +14 -0
- package/scripts/r193-limited-subject-probe.ps1 +25 -0
- package/scripts/r193-migrate-runtime-limited.ps1 +103 -0
- package/scripts/r193-owner-keygen.mjs +43 -0
- package/scripts/r193-owner-request-live.mjs +50 -0
- package/scripts/r193-owner-uac-approve.ps1 +42 -0
- package/scripts/r193-owner-uac-broker.mjs +139 -0
- package/scripts/r193-owner-uac-enroll-and-approve.ps1 +62 -0
- package/scripts/r193-test-limited-token.ps1 +49 -0
- package/scripts/r193-toolchain-inventory.ps1 +7 -0
- package/scripts/r193-uac-bridge-focused.mjs +21 -0
- package/src/deadbyte-cli.mjs +2 -1
- package/src/r188-owner-uac.mjs +105 -0
- package/src/r188-uac-boundary.mjs +21 -0
- package/src/r193-live-owner-subject.mjs +110 -0
- package/src/r193-owner-secret-acl.mjs +67 -0
- package/src/r193-owner-uac-broker.mjs +85 -0
- package/src/r193-uac-r70-bridge.mjs +54 -0
- package/src/remote-live-log.mjs +22 -1
- package/src/version.mjs +1 -1
- package/test/process-policy-refresh.test.mjs +1 -1
- package/test/r130-release-security-contract.test.mjs +8 -8
- package/test/r132-release-identity.test.mjs +7 -7
- package/test/r153-prepublish-identity.test.mjs +1 -1
- package/test/r160-release-contract.test.mjs +3 -3
- package/test/r165-live-cli-skew.test.mjs +1 -1
- package/test/r167-release-contract.test.mjs +11 -11
- package/test/r168-release-contract.test.mjs +4 -2
- package/test/r172-release-contract.test.mjs +6 -6
- package/test/r173-release-contract.test.mjs +16 -16
- package/test/r179-release-contract.test.mjs +11 -11
- package/test/r188-owner-uac.test.mjs +48 -0
- package/test/r188-uac-boundary.test.mjs +42 -0
- package/test/r190-release-contract.test.mjs +10 -10
- package/test/r191-release-contract.test.mjs +12 -12
- package/test/r192-live-log-hardening.test.mjs +50 -0
- package/test/r192-release-identity.test.mjs +40 -0
- package/test/r193-limited-migration-contract.test.mjs +26 -0
- package/test/r193-live-owner-subject.test.mjs +61 -0
- package/test/r193-native-process-observer.test.mjs +36 -0
- package/test/r193-native-token.test.mjs +43 -0
- package/test/r193-owner-enrollment-entrypoint.test.mjs +38 -0
- package/test/r193-owner-secret-acl.test.mjs +23 -0
- package/test/r193-owner-uac-broker.test.mjs +82 -0
- package/test/r193-owner-uac-entrypoint.test.mjs +36 -0
- package/test/r193-release-identity.test.mjs +56 -0
- package/test/r193-release-readiness.test.mjs +87 -0
- package/test/r193-uac-r70-bridge.test.mjs +88 -0
- package/test/r193-windows-gate.test.mjs +30 -0
- package/test/r194-npm-auth-recovery.test.mjs +77 -0
- package/test/r194-npm-preauth.test.mjs +57 -0
- package/test/r194-release-identity.test.mjs +43 -0
- package/test/r194-release-readiness.test.mjs +87 -0
- package/test/r194-windows-gate.test.mjs +21 -0
- package/test/r59-tool-surface-compat.test.mjs +1 -1
package/SBOM.cdx.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.6",
|
|
4
|
-
"serialNumber": "urn:cdx:deadbyte-mcp:
|
|
4
|
+
"serialNumber": "urn:cdx:deadbyte-mcp:r194:0.15.74",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
7
|
"component": {
|
|
8
8
|
"type": "application",
|
|
9
9
|
"name": "deadbyte-mcp",
|
|
10
|
-
"version": "0.15.
|
|
10
|
+
"version": "0.15.74"
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"components": [
|
|
@@ -65,6 +65,18 @@
|
|
|
65
65
|
"type": "library",
|
|
66
66
|
"name": "@modelcontextprotocol/core",
|
|
67
67
|
"version": "2.3.1"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"type": "file",
|
|
71
|
+
"name": "deadbyte-owner-token-r193.exe",
|
|
72
|
+
"version": "0.15.73",
|
|
73
|
+
"hashes": [
|
|
74
|
+
{
|
|
75
|
+
"alg": "SHA-256",
|
|
76
|
+
"content": "d554d732872f3d671fd2fb63c11fc0dac1f8cae377259c6d64dd0c5b3762f2b8"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"evidence_status": "PROTECTED_FOCUSED_AND_FULL_VERIFIED_PREPUBLICATION"
|
|
68
80
|
}
|
|
69
81
|
]
|
|
70
82
|
}
|
package/TEST-MATRIX.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deadbyte.test-matrix.v1",
|
|
3
|
-
"version": "0.15.
|
|
4
|
-
"train": "
|
|
3
|
+
"version": "0.15.74",
|
|
4
|
+
"train": "R194",
|
|
5
5
|
"primary_platform": "win32-x64",
|
|
6
6
|
"reference": {
|
|
7
7
|
"package": "@wonderwhy-er/desktop-commander",
|
|
@@ -154,6 +154,11 @@
|
|
|
154
154
|
"id": "r179-live-log-and-foreground",
|
|
155
155
|
"command": "Run Ctrl+C, restart, crash and concurrent sessions with pre-existing standing grants and confirm no implicit revocation",
|
|
156
156
|
"expected": "Owner standing grants unchanged; observation-only marker CAS; signed audit remains verifiable"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"id": "r192-live-log-hardening",
|
|
160
|
+
"gate": "R192 regression preserves clean default live logs, sanitization and bounded log rotation",
|
|
161
|
+
"status": "PASS_FOCUSED_31_0"
|
|
157
162
|
}
|
|
158
163
|
],
|
|
159
164
|
"observed_pre_release_evidence": {
|
|
@@ -729,5 +734,42 @@
|
|
|
729
734
|
"preflight_acl_behavior": "ASSERT_TRUSTED_AND_UNTRUSTED_PATHS_BY_ACTUAL_R89",
|
|
730
735
|
"release_contract_changes": "R132_R59_README_EXACT_01571",
|
|
731
736
|
"full_protected_regression": "PENDING_FRESH_PROTECTED_CANDIDATE_D"
|
|
737
|
+
},
|
|
738
|
+
"r192": {
|
|
739
|
+
"focused": "PASS_31_FAIL_0",
|
|
740
|
+
"integration": "PENDING_FULL_REGRESSION",
|
|
741
|
+
"protected_full": "NOT_RUN",
|
|
742
|
+
"npm_pack": "PENDING",
|
|
743
|
+
"npm_publish": "NOT_RUN",
|
|
744
|
+
"public_tool_delta": 0,
|
|
745
|
+
"authority_policy_delta": 0
|
|
746
|
+
},
|
|
747
|
+
"r193": {
|
|
748
|
+
"focused": "PASS_80_FAIL_0_SKIP_0",
|
|
749
|
+
"protected_focused": "PASS_60_FAIL_0_SKIP_1_OWNER_ENROLLMENT_BOUNDARY",
|
|
750
|
+
"protected_focused_transcript_sha256": "44228e5f21f21b86b01a2df028cb9e71aa6f827aa8750b9a616cfec4be70ae5a",
|
|
751
|
+
"protected_full": "PASS_2136_FAIL_0_SKIP_51_PRE_FINAL_SOURCE_MUTATION",
|
|
752
|
+
"protected_full_transcript_sha256": "2c829f178c09190e0e09d7b7731b18621de5b610f337f6b9aab67f1c484a860b",
|
|
753
|
+
"manifest": "PENDING_FINAL_METADATA_FREEZE",
|
|
754
|
+
"windows_gate": "PENDING_FRESH_EXACT_BYTES_AFTER_READINESS_GUARD",
|
|
755
|
+
"publish_readiness_guard": "PASS_RED_THEN_GREEN_10_TESTS_WITH_CANONICAL_ENTRYPOINT",
|
|
756
|
+
"npm_pack": "PENDING",
|
|
757
|
+
"npm_publish": "NOT_RUN",
|
|
758
|
+
"production_activation": "NOT_RUN",
|
|
759
|
+
"owner_enrollment": "NOT_RUN",
|
|
760
|
+
"public_tool_delta": 0,
|
|
761
|
+
"authority_scope_delta": 0
|
|
762
|
+
},
|
|
763
|
+
"r194": {
|
|
764
|
+
"focused": "PENDING_FRESH_SOURCE",
|
|
765
|
+
"full": "PENDING_FRESH_PROTECTED",
|
|
766
|
+
"manifest": "PENDING_NEW_SEAL",
|
|
767
|
+
"windows_gate": "PENDING",
|
|
768
|
+
"npm_pack": "PENDING",
|
|
769
|
+
"npm_publish": "NOT_RUN",
|
|
770
|
+
"production_activation": "NOT_RUN",
|
|
771
|
+
"owner_enrollment": "NOT_RUN",
|
|
772
|
+
"public_tool_delta": 0,
|
|
773
|
+
"authority_scope_delta": 0
|
|
732
774
|
}
|
|
733
775
|
}
|
|
Binary file
|
package/bridge/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "deadbyte.process-policy.v1",
|
|
3
3
|
"enabled": true,
|
|
4
|
-
"grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
5
|
-
"state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
4
|
+
"grant_file": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.74-r194-npm-auth-recovery\\controller\\runtime\\process-grant.json",
|
|
5
|
+
"state_dir": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.74-r194-npm-auth-recovery\\controller\\runtime\\process-state",
|
|
6
6
|
"native_host": {
|
|
7
|
-
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
7
|
+
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.74-r194-npm-auth-recovery\\bin\\deadbyte-process-host.exe",
|
|
8
8
|
"sha256": "daf9cfb371bee88cafbf5597eaa507fec504dbe0b0ddd40d0c3c2e02817f49e4"
|
|
9
9
|
},
|
|
10
10
|
"roots": {
|
|
11
11
|
"core": {
|
|
12
|
-
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.
|
|
12
|
+
"path": "D:\\Projects\\deadbyte-mcp\\development\\deadbyte-mcp-0.15.74-r194-npm-auth-recovery",
|
|
13
13
|
"deny_paths": [
|
|
14
14
|
"node_modules",
|
|
15
15
|
"controller/runtime",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deadbyte-mcp",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.74",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "deadbyte-mcp",
|
|
9
|
-
"version": "0.15.
|
|
9
|
+
"version": "0.15.74",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"@modelcontextprotocol/server",
|
|
12
12
|
"@modelcontextprotocol/client",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
R192 live log hardening
|
|
2
|
+
target 0.15.72
|
|
3
|
+
|
|
4
|
+
the default npx remote console stays compact
|
|
5
|
+
signed tool audit is the authority for execution results
|
|
6
|
+
console output never grants or restores machine authority
|
|
7
|
+
|
|
8
|
+
changes
|
|
9
|
+
- extra screening and byte bounds for verbose runtime diagnostics
|
|
10
|
+
- keep tool name status and duration while reducing noisy reason text
|
|
11
|
+
- remove old log cursors and partial-line fragments after discovery drops files
|
|
12
|
+
- preserve independent START and terminal result lines for mutations
|
|
13
|
+
- keep heartbeat folding timeline filters and trace formatting
|
|
14
|
+
- no change to the public MCP tool catalog or authority policy
|
|
15
|
+
|
|
16
|
+
integration
|
|
17
|
+
src/deadbyte-cli.mjs reads and tracks foreground streams
|
|
18
|
+
src/remote-live-log.mjs formats audit-safe progress and prunes old readers
|
|
19
|
+
src/remote-log-decode-r60.mjs handles bounded append and file identity
|
|
20
|
+
src/tool-audit.mjs remains the signed and sanitized audit source
|
|
21
|
+
|
|
22
|
+
reference study
|
|
23
|
+
D:\Projects\deadbyte-mcp\references
|
|
24
|
+
read-only comparison of remote MCP/Commander implementations
|
|
25
|
+
no donor code imported or copied into R192
|
|
26
|
+
|
|
27
|
+
verification
|
|
28
|
+
R192 focused 31 pass 0 fail
|
|
29
|
+
R192 extended release identity 60 pass 0 fail
|
|
30
|
+
full workspace regression not yet verified
|
|
31
|
+
protected Windows package test not yet verified
|
|
32
|
+
npm publication not yet verified
|
|
33
|
+
production activation not run
|
|
34
|
+
|
|
35
|
+
release constraints
|
|
36
|
+
0.15.71 remains the active rollback predecessor
|
|
37
|
+
no writes to installed production files or owner authority
|
|
38
|
+
do not publish before exact package verification
|
|
39
|
+
do not use npm success messages as proof of registry bytes
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// R193 native Windows token probe. Diagnostic only: NOT owner consent or a grant.
|
|
2
|
+
// It can inspect itself or one PID. A caller must bind the returned kernel
|
|
3
|
+
// creation FILETIME to an independently trusted ownership ledger.
|
|
4
|
+
#ifndef WIN32_LEAN_AND_MEAN
|
|
5
|
+
#define WIN32_LEAN_AND_MEAN
|
|
6
|
+
#endif
|
|
7
|
+
#include <windows.h>
|
|
8
|
+
#include <sddl.h>
|
|
9
|
+
#include <cstring>
|
|
10
|
+
#include <iomanip>
|
|
11
|
+
#include <iostream>
|
|
12
|
+
#include <limits>
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <vector>
|
|
15
|
+
|
|
16
|
+
static bool info(HANDLE token, TOKEN_INFORMATION_CLASS klass, void* output, DWORD size) {
|
|
17
|
+
DWORD written = 0;
|
|
18
|
+
return GetTokenInformation(token, klass, output, size, &written) != 0 && written >= size;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
struct TokenReport {
|
|
22
|
+
bool valid = false;
|
|
23
|
+
bool elevated = false;
|
|
24
|
+
bool admin_enabled = false;
|
|
25
|
+
DWORD integrity_rid = 0;
|
|
26
|
+
TOKEN_ELEVATION_TYPE elevation_type = TokenElevationTypeDefault;
|
|
27
|
+
TOKEN_TYPE token_type = TokenPrimary;
|
|
28
|
+
DWORD session_id = 0;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
static TokenReport inspect_token(HANDLE process) {
|
|
32
|
+
TokenReport out{};
|
|
33
|
+
HANDLE token = nullptr;
|
|
34
|
+
if (!OpenProcessToken(process, TOKEN_QUERY | TOKEN_DUPLICATE, &token)) return out;
|
|
35
|
+
TOKEN_ELEVATION elevation{};
|
|
36
|
+
TOKEN_ELEVATION_TYPE elevation_type = TokenElevationTypeDefault;
|
|
37
|
+
TOKEN_TYPE token_type = TokenPrimary;
|
|
38
|
+
DWORD session_id = 0;
|
|
39
|
+
bool valid = info(token, TokenElevation, &elevation, sizeof(elevation))
|
|
40
|
+
&& info(token, TokenElevationType, &elevation_type, sizeof(elevation_type))
|
|
41
|
+
&& info(token, TokenType, &token_type, sizeof(token_type))
|
|
42
|
+
&& info(token, TokenSessionId, &session_id, sizeof(session_id));
|
|
43
|
+
|
|
44
|
+
PSID administrators = nullptr;
|
|
45
|
+
BOOL admin_enabled = FALSE;
|
|
46
|
+
HANDLE membership_token = nullptr;
|
|
47
|
+
SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
|
|
48
|
+
if (valid) {
|
|
49
|
+
valid = AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
|
50
|
+
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &administrators) != 0;
|
|
51
|
+
if (valid) valid = DuplicateToken(token, SecurityIdentification, &membership_token) != 0;
|
|
52
|
+
if (valid) valid = CheckTokenMembership(membership_token, administrators, &admin_enabled) != 0;
|
|
53
|
+
}
|
|
54
|
+
DWORD len = 0;
|
|
55
|
+
DWORD integrity_rid = 0;
|
|
56
|
+
if (valid) {
|
|
57
|
+
GetTokenInformation(token, TokenIntegrityLevel, nullptr, 0, &len);
|
|
58
|
+
valid = GetLastError() == ERROR_INSUFFICIENT_BUFFER
|
|
59
|
+
&& len >= sizeof(TOKEN_MANDATORY_LABEL) && len <= 65536;
|
|
60
|
+
if (valid) {
|
|
61
|
+
std::vector<unsigned char> buffer(len);
|
|
62
|
+
valid = GetTokenInformation(token, TokenIntegrityLevel, buffer.data(), len, &len) != 0;
|
|
63
|
+
if (valid) {
|
|
64
|
+
auto* label = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buffer.data());
|
|
65
|
+
auto* sid = label->Label.Sid;
|
|
66
|
+
valid = IsValidSid(sid) != 0 && *GetSidSubAuthorityCount(sid) >= 1;
|
|
67
|
+
if (valid) integrity_rid = *GetSidSubAuthority(sid, *GetSidSubAuthorityCount(sid)-1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (membership_token) CloseHandle(membership_token);
|
|
72
|
+
if (administrators) FreeSid(administrators);
|
|
73
|
+
CloseHandle(token);
|
|
74
|
+
out.valid = valid;
|
|
75
|
+
out.elevated = elevation.TokenIsElevated != 0;
|
|
76
|
+
out.admin_enabled = admin_enabled != FALSE;
|
|
77
|
+
out.integrity_rid = integrity_rid;
|
|
78
|
+
out.elevation_type = elevation_type;
|
|
79
|
+
out.token_type = token_type;
|
|
80
|
+
out.session_id = session_id;
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static bool standard_token(const TokenReport& report) {
|
|
85
|
+
return !report.elevated && !report.admin_enabled
|
|
86
|
+
&& report.token_type == TokenPrimary
|
|
87
|
+
&& report.integrity_rid >= SECURITY_MANDATORY_MEDIUM_RID
|
|
88
|
+
&& report.integrity_rid < SECURITY_MANDATORY_HIGH_RID
|
|
89
|
+
&& report.elevation_type != TokenElevationTypeFull;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
int main(int argc, char** argv) {
|
|
93
|
+
const bool report = argc == 2 && std::strcmp(argv[1], "--report") == 0;
|
|
94
|
+
const bool require_standard = argc == 2 && std::strcmp(argv[1], "--require-standard") == 0;
|
|
95
|
+
const bool inspect_pid = argc == 3 && std::strcmp(argv[1], "--inspect-pid") == 0;
|
|
96
|
+
if (!report && !require_standard && !inspect_pid) {
|
|
97
|
+
std::cerr << "usage: deadbyte-owner-token-r193.exe --report|--require-standard|--inspect-pid PID\n";
|
|
98
|
+
return 64;
|
|
99
|
+
}
|
|
100
|
+
if (inspect_pid) {
|
|
101
|
+
std::string raw(argv[2]);
|
|
102
|
+
size_t consumed = 0;
|
|
103
|
+
unsigned long long parsed = 0;
|
|
104
|
+
try { parsed = std::stoull(raw, &consumed, 10); }
|
|
105
|
+
catch (...) { std::cerr << "R193_TARGET_PID_INVALID\n"; return 64; }
|
|
106
|
+
if (consumed != raw.size() || parsed < 1 || parsed > std::numeric_limits<DWORD>::max()) {
|
|
107
|
+
std::cerr << "R193_TARGET_PID_INVALID\n";
|
|
108
|
+
return 64;
|
|
109
|
+
}
|
|
110
|
+
const DWORD pid = static_cast<DWORD>(parsed);
|
|
111
|
+
HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
|
112
|
+
if (!process) { std::cerr << "R193_TARGET_PROCESS_UNAVAILABLE\n"; return 72; }
|
|
113
|
+
FILETIME created{}, exited{}, kernel{}, user{};
|
|
114
|
+
const bool times = GetProcessTimes(process, &created, &exited, &kernel, &user) != 0;
|
|
115
|
+
const TokenReport target = inspect_token(process);
|
|
116
|
+
CloseHandle(process);
|
|
117
|
+
if (!times || !target.valid) {
|
|
118
|
+
std::cerr << "R193_TARGET_TOKEN_INSPECTION_FAILED\n";
|
|
119
|
+
return 73;
|
|
120
|
+
}
|
|
121
|
+
ULARGE_INTEGER identity{};
|
|
122
|
+
identity.LowPart = created.dwLowDateTime;
|
|
123
|
+
identity.HighPart = created.dwHighDateTime;
|
|
124
|
+
std::cout << "{\"schema\":\"deadbyte.r193-native-process-token.v1\",\"pid\":" << pid
|
|
125
|
+
<< ",\"creation_filetime_hex\":\"" << std::hex << std::setfill('0') << std::setw(16)
|
|
126
|
+
<< identity.QuadPart << std::dec
|
|
127
|
+
<< "\",\"alive\":true,\"identity_verified\":true,\"elevated\":"
|
|
128
|
+
<< (target.elevated ? "true" : "false")
|
|
129
|
+
<< ",\"admin_enabled\":" << (target.admin_enabled ? "true" : "false")
|
|
130
|
+
<< ",\"integrity_rid\":" << target.integrity_rid
|
|
131
|
+
<< ",\"elevation_type\":" << static_cast<int>(target.elevation_type)
|
|
132
|
+
<< ",\"token_type\":\"" << (target.token_type == TokenPrimary ? "primary" : "impersonation")
|
|
133
|
+
<< "\",\"session_id\":" << target.session_id
|
|
134
|
+
<< ",\"owner_approved\":false,\"authority_granted\":false}\n";
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const TokenReport self = inspect_token(GetCurrentProcess());
|
|
139
|
+
if (!self.valid) {
|
|
140
|
+
std::cerr << "R193_TOKEN_INSPECTION_FAILED\n";
|
|
141
|
+
return 71;
|
|
142
|
+
}
|
|
143
|
+
const bool standard = standard_token(self);
|
|
144
|
+
const char* reason = standard ? "STANDARD_TOKEN_OBSERVED" : "NOT_STANDARD_TOKEN";
|
|
145
|
+
std::cout << "{\"schema\":\"deadbyte.r193-native-token.v1\",\"status\":\""
|
|
146
|
+
<< (standard ? "STANDARD_TOKEN_OBSERVED" : "BLOCKED")
|
|
147
|
+
<< "\",\"reason\":\"" << reason
|
|
148
|
+
<< "\",\"elevated\":" << (self.elevated ? "true" : "false")
|
|
149
|
+
<< ",\"admin_enabled\":" << (self.admin_enabled ? "true" : "false")
|
|
150
|
+
<< ",\"integrity_rid\":" << self.integrity_rid
|
|
151
|
+
<< ",\"elevation_type\":" << static_cast<int>(self.elevation_type)
|
|
152
|
+
<< ",\"token_type\":" << static_cast<int>(self.token_type)
|
|
153
|
+
<< ",\"session_id\":" << self.session_id
|
|
154
|
+
<< ",\"parent_independence_verified\":false,\"owner_approved\":false,\"authority_granted\":false}\n";
|
|
155
|
+
return require_standard && !standard ? 3 : 0;
|
|
156
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deadbyte-mcp",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.74",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Authenticated MCP agentic runtime with signed skills, persistent model backends, identity-bound remote devices, durable job supervision, immutable release slots, and separately revocable machine authority.",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"r67:shard:run": "node scripts/r67-regression-shard-run.mjs",
|
|
96
96
|
"r67:shard:verify": "node scripts/r67-regression-reconcile.mjs",
|
|
97
97
|
"r167:focused:test": "node --test --test-concurrency=1 test/r167-activation-path.test.mjs test/r167-release-contract.test.mjs test/r167-release-readiness.test.mjs test/r160-release-contract.test.mjs test/r158-epoch-bootstrap.test.mjs test/r65-activation-orchestration.test.mjs",
|
|
98
|
-
"gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-
|
|
98
|
+
"gate:windows": "powershell -NoProfile -ExecutionPolicy Bypass -File scripts/gate-windows-r194.ps1 -Stage all",
|
|
99
99
|
"r168:focused:test": "node test/r168-combined-targeted-runner.mjs",
|
|
100
100
|
"r168:release:verify": "node scripts/npm-release-r48.mjs --verify-only",
|
|
101
101
|
"r172:focused:test": "node --test --test-concurrency=1 test/r172-activation-recovery.test.mjs test/r172-release-contract.test.mjs test/r169-delegate-active.test.mjs test/r169-delegate-cli-integration.test.mjs test/r65-activation-lock-recovery.test.mjs test/r65-activation-orchestration.test.mjs",
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#requires -Version 5.1
|
|
2
|
+
[CmdletBinding()]
|
|
3
|
+
param(
|
|
4
|
+
[ValidateSet('preflight','focused','full','manifest','doctor','all')][string]$Stage='preflight'
|
|
5
|
+
)
|
|
6
|
+
Set-StrictMode -Version Latest
|
|
7
|
+
$ErrorActionPreference='Stop'
|
|
8
|
+
$repo=Split-Path -Parent $PSScriptRoot
|
|
9
|
+
$productionState=Join-Path $env:USERPROFILE '.deadbyte-mcp'
|
|
10
|
+
$parentId='v0.15.72-0a5d9436e06e2d9e'
|
|
11
|
+
$parentSha='0a5d9436e06e2d9e7cf9179417465955d8ca5ba88655b13dd019190243c1cc90'
|
|
12
|
+
$parentGen='aec7b998306a3bbbcc59088648e7bc46ca7e203d749d4550b5b5f372032f92b0'
|
|
13
|
+
$parentTarball='15ab5d9808cbca342aee3f64c6d1123e8fbb72964674eab460e355c8675bf84d'
|
|
14
|
+
$nativeNode='C:\Program Files\nodejs\node.exe'
|
|
15
|
+
$node=if(Test-Path -LiteralPath $nativeNode -PathType Leaf){$nativeNode}else{(Get-Command node -ErrorAction Stop).Source}
|
|
16
|
+
function Sha([string]$file){
|
|
17
|
+
$sha=[Security.Cryptography.SHA256]::Create()
|
|
18
|
+
try{$stream=[IO.File]::OpenRead($file);try{return ([BitConverter]::ToString($sha.ComputeHash($stream))).Replace('-','').ToLowerInvariant()}finally{$stream.Dispose()}}finally{$sha.Dispose()}
|
|
19
|
+
}
|
|
20
|
+
function Need([bool]$condition,[string]$message){if(-not $condition){throw $message}}
|
|
21
|
+
function Run-Node([string]$label,[string[]]$nodeArgs){
|
|
22
|
+
Need ($null -ne $nodeArgs -and $nodeArgs.Count -gt 0) "R193_${label}_NO_NODE_ARGUMENTS"
|
|
23
|
+
Write-Output "R193_STAGE_START=$label"
|
|
24
|
+
$global:LASTEXITCODE=0
|
|
25
|
+
& $node @nodeArgs
|
|
26
|
+
$exit=$global:LASTEXITCODE
|
|
27
|
+
if($exit -ne 0){throw "R193_${label}_FAILED exit=$exit"}
|
|
28
|
+
Write-Output "R193_STAGE_PASS=$label"
|
|
29
|
+
}
|
|
30
|
+
Push-Location $repo
|
|
31
|
+
$previousExpectedDevelopmentRoot=$env:DEADBYTE_EXPECTED_DEVELOPMENT_ROOT
|
|
32
|
+
try{
|
|
33
|
+
$pkg=Get-Content -LiteralPath 'package.json' -Raw | ConvertFrom-Json
|
|
34
|
+
$release=Get-Content -LiteralPath 'RELEASE.json' -Raw | ConvertFrom-Json
|
|
35
|
+
Need (-not [string]::IsNullOrWhiteSpace([string]$release.r192.development_policy_root)) 'R193_DEVELOPMENT_PROVENANCE_ROOT_MISSING'
|
|
36
|
+
$env:DEADBYTE_EXPECTED_DEVELOPMENT_ROOT=[IO.Path]::GetFullPath([string]$release.r192.development_policy_root)
|
|
37
|
+
Need ($pkg.version -eq '0.15.73' -and $release.version -eq '0.15.73' -and $release.train -eq 'R193') 'R193_CANDIDATE_VERSION_DRIFT'
|
|
38
|
+
Need ($release.source_predecessor.version -eq '0.15.72' -and $release.source_predecessor.train -eq 'R192') 'R193_SOURCE_PREDECESSOR_VERSION_DRIFT'
|
|
39
|
+
Need ($release.source_predecessor.manifest_sha256 -eq $parentSha -and $release.source_predecessor.tarball_sha256 -eq $parentTarball) 'R193_SOURCE_PREDECESSOR_IDENTITY_DRIFT'
|
|
40
|
+
Need ($release.runtime_predecessor.release_id -eq $parentId -and $release.runtime_predecessor.manifest_sha256 -eq $parentSha -and $release.runtime_predecessor.generation_manifest_sha256 -eq $parentGen) 'R193_RUNTIME_PREDECESSOR_IDENTITY_DRIFT'
|
|
41
|
+
$active=Get-Content -LiteralPath (Join-Path $productionState 'active-release.json') -Raw | ConvertFrom-Json
|
|
42
|
+
Need ($active.version -eq '0.15.72' -and $active.release_id -eq $parentId -and $active.manifest_sha256 -eq $parentSha -and $active.generation_manifest_sha256 -eq $parentGen) 'R193_ACTIVE_RUNTIME_DRIFT'
|
|
43
|
+
Need ((Sha (Join-Path $active.release_root 'MANIFEST.SHA256')) -eq $parentSha) 'R193_ACTIVE_MANIFEST_MISMATCH'
|
|
44
|
+
Write-Output 'R193_PREDECESSOR_PREFLIGHT=PASS'
|
|
45
|
+
if($Stage -eq 'preflight'){return}
|
|
46
|
+
if($Stage -in @('focused','all')){
|
|
47
|
+
$focused=@(
|
|
48
|
+
'test/r70-owner-approval.test.mjs',
|
|
49
|
+
'test/r89-privileged-install-boundary.test.mjs',
|
|
50
|
+
'test/r186-controller-owner-grant.test.mjs',
|
|
51
|
+
'test/r186-owner-consent-preflight.test.mjs',
|
|
52
|
+
'test/r186-owner-enrollment.test.mjs',
|
|
53
|
+
'test/r186-owner-grant-broker.test.mjs',
|
|
54
|
+
'test/r186-owner-local-signing.test.mjs',
|
|
55
|
+
'test/r186-owner-request.test.mjs',
|
|
56
|
+
'test/r186-owner-review-export.test.mjs',
|
|
57
|
+
'test/r188-owner-uac.test.mjs',
|
|
58
|
+
'test/r188-uac-boundary.test.mjs',
|
|
59
|
+
'test/r193-limited-migration-contract.test.mjs',
|
|
60
|
+
'test/r193-live-owner-subject.test.mjs',
|
|
61
|
+
'test/r193-native-process-observer.test.mjs',
|
|
62
|
+
'test/r193-native-token.test.mjs',
|
|
63
|
+
'test/r193-owner-enrollment-entrypoint.test.mjs',
|
|
64
|
+
'test/r193-owner-secret-acl.test.mjs',
|
|
65
|
+
'test/r193-owner-uac-broker.test.mjs',
|
|
66
|
+
'test/r193-owner-uac-entrypoint.test.mjs',
|
|
67
|
+
'test/r193-release-readiness.test.mjs',
|
|
68
|
+
'test/r193-release-identity.test.mjs',
|
|
69
|
+
'test/r193-uac-r70-bridge.test.mjs',
|
|
70
|
+
'test/r193-windows-gate.test.mjs'
|
|
71
|
+
)
|
|
72
|
+
Run-Node -label 'focused' -nodeArgs (@('--test','--test-reporter=tap','--test-concurrency=1')+$focused)
|
|
73
|
+
if($Stage -eq 'focused'){return}
|
|
74
|
+
}
|
|
75
|
+
if($Stage -in @('full','all')){
|
|
76
|
+
$previousCrossVolume=$env:DEADBYTE_TEST_CROSS_VOLUME_ROOT
|
|
77
|
+
$tempDrive=[IO.Path]::GetPathRoot([IO.Path]::GetFullPath($env:TEMP))
|
|
78
|
+
$scratchDrive=if($tempDrive -ieq 'D:\'){'C:\'}else{'D:\'}
|
|
79
|
+
Need (Test-Path -LiteralPath $scratchDrive -PathType Container) 'R193_CROSS_VOLUME_DRIVE_UNAVAILABLE'
|
|
80
|
+
$crossVolume=Join-Path $scratchDrive 'DEADBYTE-R193-CrossVolume'
|
|
81
|
+
try{
|
|
82
|
+
[IO.Directory]::CreateDirectory($crossVolume)|Out-Null
|
|
83
|
+
$env:DEADBYTE_TEST_CROSS_VOLUME_ROOT=$crossVolume
|
|
84
|
+
Run-Node -label 'full' -nodeArgs @('--test','--test-reporter=tap','--test-concurrency=4','test/*.test.mjs')
|
|
85
|
+
}finally{$env:DEADBYTE_TEST_CROSS_VOLUME_ROOT=$previousCrossVolume}
|
|
86
|
+
if($Stage -eq 'full'){return}
|
|
87
|
+
}
|
|
88
|
+
if($Stage -in @('manifest','all')){
|
|
89
|
+
Run-Node -label 'manifest' -nodeArgs @('scripts/release-manifest.mjs','verify')
|
|
90
|
+
if($Stage -eq 'manifest'){return}
|
|
91
|
+
}
|
|
92
|
+
if($Stage -in @('doctor','all')){
|
|
93
|
+
$previousStateRoot=$env:DEADBYTE_STATE_ROOT
|
|
94
|
+
$isolated=Join-Path $env:TEMP ('deadbyte-r193-doctor-'+[guid]::NewGuid().ToString('N'))
|
|
95
|
+
try{
|
|
96
|
+
[IO.Directory]::CreateDirectory($isolated)|Out-Null
|
|
97
|
+
$env:DEADBYTE_STATE_ROOT=$isolated
|
|
98
|
+
Run-Node -label 'isolated_doctor' -nodeArgs @('src/deadbyte-cli.mjs','doctor')
|
|
99
|
+
}finally{
|
|
100
|
+
$env:DEADBYTE_STATE_ROOT=$previousStateRoot
|
|
101
|
+
Remove-Item -LiteralPath $isolated -Recurse -Force -ErrorAction SilentlyContinue
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
Write-Output 'R193_WINDOWS_CANDIDATE_GATE=PASS_PREPUBLICATION'
|
|
105
|
+
}finally{
|
|
106
|
+
$env:DEADBYTE_EXPECTED_DEVELOPMENT_ROOT=$previousExpectedDevelopmentRoot
|
|
107
|
+
Pop-Location
|
|
108
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#requires -Version 5.1
|
|
2
|
+
[CmdletBinding()]
|
|
3
|
+
param(
|
|
4
|
+
[ValidateSet('preflight','focused','full','manifest','doctor','all')][string]$Stage='preflight'
|
|
5
|
+
)
|
|
6
|
+
Set-StrictMode -Version Latest
|
|
7
|
+
$ErrorActionPreference='Stop'
|
|
8
|
+
$repo=Split-Path -Parent $PSScriptRoot
|
|
9
|
+
$productionState=Join-Path $env:USERPROFILE '.deadbyte-mcp'
|
|
10
|
+
$parentId='v0.15.72-0a5d9436e06e2d9e'
|
|
11
|
+
$parentSha='0a5d9436e06e2d9e7cf9179417465955d8ca5ba88655b13dd019190243c1cc90'
|
|
12
|
+
$parentGen='aec7b998306a3bbbcc59088648e7bc46ca7e203d749d4550b5b5f372032f92b0'
|
|
13
|
+
$parentTarball='15ab5d9808cbca342aee3f64c6d1123e8fbb72964674eab460e355c8675bf84d'
|
|
14
|
+
$nativeNode='C:\Program Files\nodejs\node.exe'
|
|
15
|
+
$node=if(Test-Path -LiteralPath $nativeNode -PathType Leaf){$nativeNode}else{(Get-Command node -ErrorAction Stop).Source}
|
|
16
|
+
function Sha([string]$file){
|
|
17
|
+
$sha=[Security.Cryptography.SHA256]::Create()
|
|
18
|
+
try{$stream=[IO.File]::OpenRead($file);try{return ([BitConverter]::ToString($sha.ComputeHash($stream))).Replace('-','').ToLowerInvariant()}finally{$stream.Dispose()}}finally{$sha.Dispose()}
|
|
19
|
+
}
|
|
20
|
+
function Need([bool]$condition,[string]$message){if(-not $condition){throw $message}}
|
|
21
|
+
function Run-Node([string]$label,[string[]]$nodeArgs){
|
|
22
|
+
Need ($null -ne $nodeArgs -and $nodeArgs.Count -gt 0) "R194_${label}_NO_NODE_ARGUMENTS"
|
|
23
|
+
Write-Output "R194_STAGE_START=$label"
|
|
24
|
+
$global:LASTEXITCODE=0
|
|
25
|
+
& $node @nodeArgs
|
|
26
|
+
$exit=$global:LASTEXITCODE
|
|
27
|
+
if($exit -ne 0){throw "R194_${label}_FAILED exit=$exit"}
|
|
28
|
+
Write-Output "R194_STAGE_PASS=$label"
|
|
29
|
+
}
|
|
30
|
+
Push-Location $repo
|
|
31
|
+
$previousExpectedDevelopmentRoot=$env:DEADBYTE_EXPECTED_DEVELOPMENT_ROOT
|
|
32
|
+
try{
|
|
33
|
+
$pkg=Get-Content -LiteralPath 'package.json' -Raw | ConvertFrom-Json
|
|
34
|
+
$release=Get-Content -LiteralPath 'RELEASE.json' -Raw | ConvertFrom-Json
|
|
35
|
+
Need (-not [string]::IsNullOrWhiteSpace([string]$release.r194.development_policy_root)) 'R194_DEVELOPMENT_PROVENANCE_ROOT_MISSING'
|
|
36
|
+
$env:DEADBYTE_EXPECTED_DEVELOPMENT_ROOT=[IO.Path]::GetFullPath([string]$release.r194.development_policy_root)
|
|
37
|
+
Need ($pkg.version -eq '0.15.74' -and $release.version -eq '0.15.74' -and $release.train -eq 'R194') 'R194_CANDIDATE_VERSION_DRIFT'
|
|
38
|
+
Need ($release.source_predecessor.version -eq '0.15.73' -and $release.source_predecessor.train -eq 'R193') 'R194_SOURCE_PREDECESSOR_VERSION_DRIFT'
|
|
39
|
+
Need ($release.source_predecessor.manifest_sha256 -eq 'e0b3f8b333f1c1260a97b178d1a8beff5742355296a9fe7daba378612604a3bd' -and $release.source_predecessor.tarball_sha256 -eq '13c3dd23a535609aa53173b328c7d9299d5dcada684f3253a88af6a4b300c534') 'R194_SOURCE_PREDECESSOR_IDENTITY_DRIFT'
|
|
40
|
+
Need ($release.runtime_predecessor.release_id -eq $parentId -and $release.runtime_predecessor.manifest_sha256 -eq $parentSha -and $release.runtime_predecessor.generation_manifest_sha256 -eq $parentGen) 'R194_RUNTIME_PREDECESSOR_IDENTITY_DRIFT'
|
|
41
|
+
$active=Get-Content -LiteralPath (Join-Path $productionState 'active-release.json') -Raw | ConvertFrom-Json
|
|
42
|
+
Need ($active.version -eq '0.15.72' -and $active.release_id -eq $parentId -and $active.manifest_sha256 -eq $parentSha -and $active.generation_manifest_sha256 -eq $parentGen) 'R194_ACTIVE_RUNTIME_DRIFT'
|
|
43
|
+
Need ((Sha (Join-Path $active.release_root 'MANIFEST.SHA256')) -eq $parentSha) 'R194_ACTIVE_MANIFEST_MISMATCH'
|
|
44
|
+
Write-Output 'R194_PREDECESSOR_PREFLIGHT=PASS'
|
|
45
|
+
if($Stage -eq 'preflight'){return}
|
|
46
|
+
if($Stage -in @('focused','all')){
|
|
47
|
+
$focused=@(
|
|
48
|
+
'test/r70-owner-approval.test.mjs',
|
|
49
|
+
'test/r89-privileged-install-boundary.test.mjs',
|
|
50
|
+
'test/r186-controller-owner-grant.test.mjs',
|
|
51
|
+
'test/r186-owner-consent-preflight.test.mjs',
|
|
52
|
+
'test/r186-owner-enrollment.test.mjs',
|
|
53
|
+
'test/r186-owner-grant-broker.test.mjs',
|
|
54
|
+
'test/r186-owner-local-signing.test.mjs',
|
|
55
|
+
'test/r186-owner-request.test.mjs',
|
|
56
|
+
'test/r186-owner-review-export.test.mjs',
|
|
57
|
+
'test/r188-owner-uac.test.mjs',
|
|
58
|
+
'test/r188-uac-boundary.test.mjs',
|
|
59
|
+
'test/r193-limited-migration-contract.test.mjs',
|
|
60
|
+
'test/r193-live-owner-subject.test.mjs',
|
|
61
|
+
'test/r193-native-process-observer.test.mjs',
|
|
62
|
+
'test/r193-native-token.test.mjs',
|
|
63
|
+
'test/r193-owner-enrollment-entrypoint.test.mjs',
|
|
64
|
+
'test/r193-owner-secret-acl.test.mjs',
|
|
65
|
+
'test/r193-owner-uac-broker.test.mjs',
|
|
66
|
+
'test/r193-owner-uac-entrypoint.test.mjs',
|
|
67
|
+
'test/r193-release-readiness.test.mjs',
|
|
68
|
+
'test/r193-release-identity.test.mjs',
|
|
69
|
+
'test/r194-release-identity.test.mjs',
|
|
70
|
+
'test/r194-release-readiness.test.mjs',
|
|
71
|
+
'test/r193-uac-r70-bridge.test.mjs',
|
|
72
|
+
'test/r194-windows-gate.test.mjs',
|
|
73
|
+
'test/r194-npm-auth-recovery.test.mjs',
|
|
74
|
+
'test/r194-npm-preauth.test.mjs'
|
|
75
|
+
)
|
|
76
|
+
Run-Node -label 'focused' -nodeArgs (@('--test','--test-reporter=tap','--test-concurrency=1')+$focused)
|
|
77
|
+
if($Stage -eq 'focused'){return}
|
|
78
|
+
}
|
|
79
|
+
if($Stage -in @('full','all')){
|
|
80
|
+
$previousCrossVolume=$env:DEADBYTE_TEST_CROSS_VOLUME_ROOT
|
|
81
|
+
$tempDrive=[IO.Path]::GetPathRoot([IO.Path]::GetFullPath($env:TEMP))
|
|
82
|
+
$scratchDrive=if($tempDrive -ieq 'D:\'){'C:\'}else{'D:\'}
|
|
83
|
+
Need (Test-Path -LiteralPath $scratchDrive -PathType Container) 'R194_CROSS_VOLUME_DRIVE_UNAVAILABLE'
|
|
84
|
+
$crossVolume=Join-Path $scratchDrive 'DEADBYTE-R194-CrossVolume'
|
|
85
|
+
try{
|
|
86
|
+
[IO.Directory]::CreateDirectory($crossVolume)|Out-Null
|
|
87
|
+
$env:DEADBYTE_TEST_CROSS_VOLUME_ROOT=$crossVolume
|
|
88
|
+
Run-Node -label 'full' -nodeArgs @('--test','--test-reporter=tap','--test-concurrency=4','test/*.test.mjs')
|
|
89
|
+
}finally{$env:DEADBYTE_TEST_CROSS_VOLUME_ROOT=$previousCrossVolume}
|
|
90
|
+
if($Stage -eq 'full'){return}
|
|
91
|
+
}
|
|
92
|
+
if($Stage -in @('manifest','all')){
|
|
93
|
+
Run-Node -label 'manifest' -nodeArgs @('scripts/release-manifest.mjs','verify')
|
|
94
|
+
if($Stage -eq 'manifest'){return}
|
|
95
|
+
}
|
|
96
|
+
if($Stage -in @('doctor','all')){
|
|
97
|
+
$previousStateRoot=$env:DEADBYTE_STATE_ROOT
|
|
98
|
+
$isolated=Join-Path $env:TEMP ('deadbyte-r194-doctor-'+[guid]::NewGuid().ToString('N'))
|
|
99
|
+
try{
|
|
100
|
+
[IO.Directory]::CreateDirectory($isolated)|Out-Null
|
|
101
|
+
$env:DEADBYTE_STATE_ROOT=$isolated
|
|
102
|
+
Run-Node -label 'isolated_doctor' -nodeArgs @('src/deadbyte-cli.mjs','doctor')
|
|
103
|
+
}finally{
|
|
104
|
+
$env:DEADBYTE_STATE_ROOT=$previousStateRoot
|
|
105
|
+
Remove-Item -LiteralPath $isolated -Recurse -Force -ErrorAction SilentlyContinue
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
Write-Output 'R194_WINDOWS_CANDIDATE_GATE=PASS_PREPUBLICATION'
|
|
109
|
+
}finally{
|
|
110
|
+
$env:DEADBYTE_EXPECTED_DEVELOPMENT_ROOT=$previousExpectedDevelopmentRoot
|
|
111
|
+
Pop-Location
|
|
112
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// R194 publication failure boundary: do not infer auth failure from a generic 404.
|
|
2
|
+
// Only an explicit npm auth code, or the exact npm registry PUT permission refusal,
|
|
3
|
+
// can be treated as a definitively rejected submission.
|
|
4
|
+
const AUTH_CODE = /(?:^|\s)(?:E401|E403|EOTP|ENEEDAUTH|EAUTH)(?:\s|$)/i;
|
|
5
|
+
const PERMISSION = /(?:you do not have permission to access it|you (?:don't|do not) have permission to publish|permission denied|forbidden|not authorized)/i;
|
|
6
|
+
const REGISTRY_PUT = /\b404\s+Not\s+Found\s+-\s+PUT\s+https:\/\/registry\.npmjs\.org\/deadbyte-mcp(?:\s|\?|\b)/i;
|
|
7
|
+
export function classifyNpmPublishFailure({exitCode,output}={}){
|
|
8
|
+
if(exitCode===0)return 'SUBMISSION_ACCEPTED';
|
|
9
|
+
const text=typeof output==='string'?output.slice(-65536):'';
|
|
10
|
+
if(AUTH_CODE.test(text))return 'EAUTH';
|
|
11
|
+
if(REGISTRY_PUT.test(text)&&PERMISSION.test(text))return 'EAUTH';
|
|
12
|
+
return 'OUTCOME_UNKNOWN';
|
|
13
|
+
}
|