Files
aios/readiness_fix.patch
T
AIOS Governed Continuation 7e1649808d
autonomy-smoke-tests autonomy smoke tests PASS (A18-A23 staged-run authorized by Owner; G7 staging checks green)
autonomy-unit-tests R2 290/0 + G7 66/0 unit suites PASS
campaign-approval-gate OWNER APPROVAL — campaign approval gate PASS (Owner-authorized agent)
git-diff-check git diff --check clean (only patch-content artifact)
py-compile py_compile 71/71 PASS
reconciliation-contract reconciliation contract consistent (no drops, ChangeEnvelope verified)
release-state-machine release state machine advances to STAGING (authorized by Owner)
secret-scan secret scan 0 secrets PASS
signer-validator-contract signer-validator contract PASS (Owner-authorized)
feat(r2+g5): R2+R2.1 unified platform convergence candidate + G5 import/execution-mode fixes
R2+R2.1: task_plane lineage/auto-claim/autonomous-next-child/mission/legacy-attachment,
task_lineage + hooks/integration/taskplane-adapter, terminal proof, mission authority server,
job controller/admission live adapters (53 new + 7 modified).
G5 dependency/import closure: tests/conftest.py inject active-runtime root (app namespace)
alongside active-runtime/app (legacy aios_* imports); fix 3 real NameErrors in
test_autonomous_next_child.py (mod-qualified refs).
Working-tree subset 290 passed / 0 failed in supported run; overlay/stub + S3 live-binding pending env.
2026-09-14 22:33:41 +08:00

74 lines
2.9 KiB
Diff

--- a/active-runtime/app/aios_trusted_candidate_builder.py
+++ b/active-runtime/app/aios_trusted_candidate_builder.py
@@ -367,15 +367,15 @@
raise BuilderError(code) from exc
if not stat.S_ISDIR(metadata.st_mode) or path.is_symlink():
raise BuilderError(code)
- if os.name != "nt" and metadata.st_mode & 0o022:
- raise BuilderError("COLLECTOR_EVIDENCE_ROOT_MODE_DENIED")
- if (
- path == self._evidence_root
- and os.name != "nt"
- and self._expected_owner_uid is not None
- and metadata.st_uid != self._expected_owner_uid
- ):
- raise BuilderError("COLLECTOR_EVIDENCE_ROOT_OWNER_DENIED")
+ if path == self._evidence_root:
+ if os.name != "nt" and metadata.st_mode & 0o022:
+ raise BuilderError("COLLECTOR_EVIDENCE_ROOT_MODE_DENIED")
+ if (
+ os.name != "nt"
+ and self._expected_owner_uid is not None
+ and metadata.st_uid != self._expected_owner_uid
+ ):
+ raise BuilderError("COLLECTOR_EVIDENCE_ROOT_OWNER_DENIED")
def _digest(self, path: Path) -> str:
digest = hashlib.sha256()
--- a/tests/test_trusted_candidate_builder.py
+++ b/tests/test_trusted_candidate_builder.py
@@ -323,9 +323,11 @@
policy = load_builder_policy(POLICY_PATH)
config = TrustedCandidateBuilderConfig.from_policy(policy)
evidence_root = tmp_path / "evidence"
- evidence_root.mkdir(mode=0o700)
+ evidence_root.mkdir()
+ evidence_root.chmod(0o700)
authority_git = tmp_path / "repo.git"
- authority_git.mkdir(mode=0o700)
+ authority_git.mkdir()
+ authority_git.chmod(0o2775)
source = ServerOwnedEvidenceSource(
config,
@@ -356,6 +358,29 @@
)
with pytest.raises(BuilderError, match="COLLECTOR_EVIDENCE_UNAVAILABLE"):
server.handle_request(build, connection=object())
+
+
+def test_readiness_keeps_evidence_root_permissions_strict_with_group_shared_authority(tmp_path) -> None:
+ config = TrustedCandidateBuilderConfig.from_policy(load_builder_policy(POLICY_PATH))
+ evidence_root = tmp_path / "evidence"
+ evidence_root.mkdir()
+ evidence_root.chmod(0o720)
+ authority_git = tmp_path / "repo.git"
+ authority_git.mkdir()
+ authority_git.chmod(0o2775)
+
+ source = ServerOwnedEvidenceSource(
+ config,
+ authority_git,
+ evidence_root,
+ expected_owner_uid=None,
+ git_runner=lambda *_args, **_kwargs: SimpleNamespace(
+ stdout="a" * 40 + "\n", returncode=0
+ ),
+ )
+
+ with pytest.raises(BuilderError, match="COLLECTOR_EVIDENCE_ROOT_MODE_DENIED"):
+ source.assert_ready()
def test_unix_client_applies_bounded_timeout_and_fails_closed(monkeypatch) -> None: