mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 19:29:13 +08:00
fix(ci): authorize reconciliation apply boundaries
This commit is contained in:
@@ -75,7 +75,7 @@
|
|||||||
`44 total / 42 pass / 2 conditional Docker skip / 0 fail`,但成功场景现在额外覆盖首次 apply、mutation replay、不同 reviewer 拒绝、六个
|
`44 total / 42 pass / 2 conditional Docker skip / 0 fail`,但成功场景现在额外覆盖首次 apply、mutation replay、不同 reviewer 拒绝、六个
|
||||||
backup/apply/rollback response-loss 窗口、content-free CLI verify、identity-preserving rollback 与 rollback replay。完整 Local Owner 在受限沙箱为
|
backup/apply/rollback response-loss 窗口、content-free CLI verify、identity-preserving rollback 与 rollback replay。完整 Local Owner 在受限沙箱为
|
||||||
`266 total / 256 pass / 7 conditional skip / 3 loopback-listen EPERM`,两个对应文件在沙箱外 `15/15` 通过;package/dependency boundary 为
|
`266 total / 256 pass / 7 conditional skip / 3 loopback-listen EPERM`,两个对应文件在沙箱外 `15/15` 通过;package/dependency boundary 为
|
||||||
`69/69`。workspace 仍为 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,Local Owner 为
|
`70/70`。workspace 仍为 18 packages、`singleSourcePackages=[]`、`shallowSourcePackages=[]`,Local Owner 为
|
||||||
`168 source / 167 nested / 1 root binary entry`,没有新增 package、production dependency、daemon、listener、timer 或 `src/` 根平铺。
|
`168 source / 167 nested / 1 root binary entry`,没有新增 package、production dependency、daemon、listener、timer 或 `src/` 根平铺。
|
||||||
D-393 仍未代表完整 reconciliation:Automation 之外的 Secret、Plugin、Identity、history 等领域 adapter 尚未 apply,target service 也未获得 restart
|
D-393 仍未代表完整 reconciliation:Automation 之外的 Secret、Plugin、Identity、history 等领域 adapter 尚未 apply,target service 也未获得 restart
|
||||||
authority;后续必须先完成 apply-root 的 retention/seal 策略和跨领域 completion fence,再进入 target restart/readiness。
|
authority;后续必须先完成 apply-root 的 retention/seal 策略和跨领域 completion fence,再进入 target restart/readiness。
|
||||||
|
|||||||
@@ -2027,6 +2027,21 @@ function auditSourceImports(root, packagePath, findings) {
|
|||||||
'@qinglong/local-sqlite/authentication-read',
|
'@qinglong/local-sqlite/authentication-read',
|
||||||
].includes(specifier)
|
].includes(specifier)
|
||||||
) &&
|
) &&
|
||||||
|
!(
|
||||||
|
path.relative(packageDirectory, filePath) ===
|
||||||
|
'src/deployment/reconciliation/application/automation/applyCoordinator.ts' &&
|
||||||
|
[
|
||||||
|
'@qinglong/local-admin/reconciliation-automation-decision',
|
||||||
|
'@qinglong/local-owner-console/authenticated-command',
|
||||||
|
'@qinglong/local-sqlite/authentication-read',
|
||||||
|
'@qinglong/local-sqlite/rollout-safety',
|
||||||
|
].includes(specifier)
|
||||||
|
) &&
|
||||||
|
!(
|
||||||
|
path.relative(packageDirectory, filePath) ===
|
||||||
|
'src/deployment/reconciliation/application/automation/applyEvidence.ts' &&
|
||||||
|
specifier === '@qinglong/local-sqlite/rollout-safety'
|
||||||
|
) &&
|
||||||
!(
|
!(
|
||||||
path.relative(packageDirectory, filePath) ===
|
path.relative(packageDirectory, filePath) ===
|
||||||
'src/deployment/reconciliation/application/automation/planReader.ts' &&
|
'src/deployment/reconciliation/application/automation/planReader.ts' &&
|
||||||
@@ -2691,6 +2706,14 @@ function auditSourceImports(root, packagePath, findings) {
|
|||||||
file: 'src/deployment/reconciliation/review/issuerKeyring.ts',
|
file: 'src/deployment/reconciliation/review/issuerKeyring.ts',
|
||||||
specifiers: ['@qinglong/runtime-core/local-secret'],
|
specifiers: ['@qinglong/runtime-core/local-secret'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
file: 'src/deployment/reconciliation/application/automation/decisionCoordinator.ts',
|
||||||
|
specifiers: ['@qinglong/runtime-core/security'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: 'src/deployment/reconciliation/application/automation/applyCoordinator.ts',
|
||||||
|
specifiers: ['@qinglong/runtime-core/security'],
|
||||||
|
},
|
||||||
].some(
|
].some(
|
||||||
({ file, specifiers }) =>
|
({ file, specifiers }) =>
|
||||||
path.relative(packageDirectory, filePath) === file &&
|
path.relative(packageDirectory, filePath) === file &&
|
||||||
|
|||||||
@@ -2150,6 +2150,84 @@ test('confines reconciliation review authentication to exact read-only owners',
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('confines reconciliation automation apply authority to exact coordinators', (t) => {
|
||||||
|
const root = fs.mkdtempSync(
|
||||||
|
path.join(os.tmpdir(), 'ql3-reconciliation-automation-apply-boundary-'),
|
||||||
|
);
|
||||||
|
const automationDirectory = path.join(
|
||||||
|
root,
|
||||||
|
'packages/ql3-local-owner-cli/src/deployment/reconciliation/application/automation',
|
||||||
|
);
|
||||||
|
fs.mkdirSync(automationDirectory, { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(automationDirectory, 'decisionCoordinator.ts'),
|
||||||
|
[
|
||||||
|
"import { decide } from '@qinglong/local-admin/reconciliation-automation-decision';",
|
||||||
|
"import { authenticate } from '@qinglong/local-owner-console/authenticated-command';",
|
||||||
|
"import { database } from '@qinglong/local-sqlite/authentication-read';",
|
||||||
|
"import type { Principal } from '@qinglong/runtime-core/security';",
|
||||||
|
].join('\n'),
|
||||||
|
);
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(automationDirectory, 'applyCoordinator.ts'),
|
||||||
|
[
|
||||||
|
"import { apply } from '@qinglong/local-admin/reconciliation-automation-decision';",
|
||||||
|
"import { authenticate } from '@qinglong/local-owner-console/authenticated-command';",
|
||||||
|
"import { database } from '@qinglong/local-sqlite/authentication-read';",
|
||||||
|
"import { backup } from '@qinglong/local-sqlite/rollout-safety';",
|
||||||
|
"import type { Principal } from '@qinglong/runtime-core/security';",
|
||||||
|
].join('\n'),
|
||||||
|
);
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(automationDirectory, 'applyEvidence.ts'),
|
||||||
|
"import type { Evidence } from '@qinglong/local-sqlite/rollout-safety';",
|
||||||
|
);
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(automationDirectory, 'neighbor.ts'),
|
||||||
|
[
|
||||||
|
"import { apply } from '@qinglong/local-admin/reconciliation-automation-decision';",
|
||||||
|
"import { authenticate } from '@qinglong/local-owner-console/authenticated-command';",
|
||||||
|
"import { database } from '@qinglong/local-sqlite/authentication-read';",
|
||||||
|
"import { backup } from '@qinglong/local-sqlite/rollout-safety';",
|
||||||
|
"import type { Principal } from '@qinglong/runtime-core/security';",
|
||||||
|
].join('\n'),
|
||||||
|
);
|
||||||
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
||||||
|
|
||||||
|
const findings = [];
|
||||||
|
auditSourceImports(root, 'packages/ql3-local-owner-cli', findings);
|
||||||
|
assert.deepEqual(
|
||||||
|
findings.map(({ code, file, specifier }) => ({ code, file, specifier })),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
code: 'FORBIDDEN_LOCAL_ADOPTION_CLI_AUTHORITY_IMPORT',
|
||||||
|
file: 'packages/ql3-local-owner-cli/src/deployment/reconciliation/application/automation/neighbor.ts',
|
||||||
|
specifier: '@qinglong/local-admin/reconciliation-automation-decision',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'FORBIDDEN_LOCAL_ADOPTION_CLI_AUTHORITY_IMPORT',
|
||||||
|
file: 'packages/ql3-local-owner-cli/src/deployment/reconciliation/application/automation/neighbor.ts',
|
||||||
|
specifier: '@qinglong/local-owner-console/authenticated-command',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'FORBIDDEN_LOCAL_ADOPTION_CLI_AUTHORITY_IMPORT',
|
||||||
|
file: 'packages/ql3-local-owner-cli/src/deployment/reconciliation/application/automation/neighbor.ts',
|
||||||
|
specifier: '@qinglong/local-sqlite/authentication-read',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'FORBIDDEN_LOCAL_ADOPTION_CLI_AUTHORITY_IMPORT',
|
||||||
|
file: 'packages/ql3-local-owner-cli/src/deployment/reconciliation/application/automation/neighbor.ts',
|
||||||
|
specifier: '@qinglong/local-sqlite/rollout-safety',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'FORBIDDEN_PACKAGE_SOURCE_IMPORT',
|
||||||
|
file: 'packages/ql3-local-owner-cli/src/deployment/reconciliation/application/automation/neighbor.ts',
|
||||||
|
specifier: '@qinglong/runtime-core/security',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('deleted Owner ceremony package names remain dependency tombstones', (t) => {
|
test('deleted Owner ceremony package names remain dependency tombstones', (t) => {
|
||||||
const root = fixture(
|
const root = fixture(
|
||||||
t,
|
t,
|
||||||
|
|||||||
Reference in New Issue
Block a user