|
36 | 36 | EffectUncertaintyEvidence, |
37 | 37 | ) |
38 | 38 | from agentnet.errors import AuthenticationError, AuthorizationError, ValidationError |
39 | | -from agentnet.identity.actors import ActorKind, TrustedTransportContext, VerifiedActor |
| 39 | +from agentnet.identity.actors import TrustedTransportContext, VerifiedActor |
40 | 40 | from agentnet.identity.credential_http import ( |
41 | 41 | ExpiredBodyAndContext, |
42 | 42 | create_credential_routes, |
|
54 | 54 | ReleasedArtifactBinding, |
55 | 55 | TaskGrant, |
56 | 56 | ) |
57 | | -from agentnet.provenance import ( |
58 | | - OriginKind, |
59 | | - OriginRegistration, |
60 | | - ProvenanceDerivation, |
61 | | - ProvenanceObjectType, |
62 | | -) |
| 57 | +from agentnet.provenance_http import create_provenance_routes |
63 | 58 | from agentnet.rooms.governance import ( |
64 | 59 | RoomTransferSnapshot, |
65 | 60 | SourceTransferProposal, |
@@ -128,18 +123,6 @@ class TaskConflictAdjudicationBody(BaseModel): |
128 | 123 | decision: TaskConflictAdjudication |
129 | 124 |
|
130 | 125 |
|
131 | | -class ProvenanceOriginBody(BaseModel): |
132 | | - model_config = ConfigDict(extra="forbid", strict=True) |
133 | | - |
134 | | - registration: OriginRegistration |
135 | | - |
136 | | - |
137 | | -class ProvenanceDerivationBody(BaseModel): |
138 | | - model_config = ConfigDict(extra="forbid", strict=True) |
139 | | - |
140 | | - derivation: ProvenanceDerivation |
141 | | - |
142 | | - |
143 | 126 | class RoomCreateBody(BaseModel): |
144 | 127 | model_config = ConfigDict(extra="forbid", strict=True) |
145 | 128 |
|
@@ -565,122 +548,6 @@ async def adjudicate_task_conflict(request: Request) -> Response: |
565 | 548 | headers=RELATIONSHIP_RESPONSE_HEADERS, |
566 | 549 | ) |
567 | 550 |
|
568 | | - async def register_provenance_origin(request: Request) -> Response: |
569 | | - body, actor = await body_and_actor(request, core) |
570 | | - parsed = ProvenanceOriginBody.model_validate_json(body, strict=True) |
571 | | - registration = parsed.registration |
572 | | - if registration.domain_id != actor.domain_id: |
573 | | - raise AuthorizationError("provenance origin crossed the authenticated domain") |
574 | | - if registration.origin.kind is not OriginKind.HUMAN_INPUT: |
575 | | - raise AuthorizationError("non-human provenance origins require a composed server service") |
576 | | - if ( |
577 | | - actor.kind is not ActorKind.VERIFIED_HUMAN_HARNESS |
578 | | - or registration.origin.principal_id != actor.principal_id |
579 | | - or registration.origin.harness_id != actor.harness_id |
580 | | - ): |
581 | | - raise AuthorizationError("human provenance origin is not the authenticated human harness") |
582 | | - resource = f"provenance:{registration.object_type.value}:{registration.object_id}" |
583 | | - core._require( |
584 | | - actor=actor, |
585 | | - action="provenance.origin.register", |
586 | | - resource=resource, |
587 | | - classification=registration.classification, |
588 | | - context={ |
589 | | - "registration_digest": canonical_digest( |
590 | | - registration.model_dump(mode="json") |
591 | | - ) |
592 | | - }, |
593 | | - ) |
594 | | - record = core.provenance.register_origin(registration) |
595 | | - return JSONResponse( |
596 | | - {"provenance": record.model_dump(mode="json")}, |
597 | | - status_code=201, |
598 | | - headers=RELATIONSHIP_RESPONSE_HEADERS, |
599 | | - ) |
600 | | - |
601 | | - async def derive_provenance(request: Request) -> Response: |
602 | | - body, actor = await body_and_actor(request, core) |
603 | | - parsed = ProvenanceDerivationBody.model_validate_json(body, strict=True) |
604 | | - derivation = parsed.derivation |
605 | | - if derivation.domain_id != actor.domain_id: |
606 | | - raise AuthorizationError("derived provenance crossed the authenticated domain") |
607 | | - if actor.harness_id is None or any( |
608 | | - step.executor_harness_id != actor.harness_id |
609 | | - for step in derivation.transformations |
610 | | - ): |
611 | | - raise AuthorizationError( |
612 | | - "provenance transformation executor is not the authenticated harness" |
613 | | - ) |
614 | | - resource = f"provenance:{derivation.object_type.value}:{derivation.object_id}" |
615 | | - core._require( |
616 | | - actor=actor, |
617 | | - action="provenance.derive", |
618 | | - resource=resource, |
619 | | - classification=derivation.classification, |
620 | | - context={ |
621 | | - "derivation_digest": canonical_digest( |
622 | | - derivation.model_dump(mode="json") |
623 | | - ) |
624 | | - }, |
625 | | - ) |
626 | | - record = core.provenance.derive(derivation) |
627 | | - return JSONResponse( |
628 | | - {"provenance": record.model_dump(mode="json")}, |
629 | | - status_code=201, |
630 | | - headers=RELATIONSHIP_RESPONSE_HEADERS, |
631 | | - ) |
632 | | - |
633 | | - async def provenance_versions(request: Request) -> Response: |
634 | | - _body, actor = await body_and_actor(request, core) |
635 | | - try: |
636 | | - object_type = ProvenanceObjectType(request.path_params["object_type"]) |
637 | | - except ValueError as exc: |
638 | | - raise ValidationError("provenance object type is invalid") from exc |
639 | | - object_id = request.path_params["object_id"] |
640 | | - resource = f"provenance:{object_type.value}:{object_id}" |
641 | | - core._require( |
642 | | - actor=actor, |
643 | | - action="provenance.read", |
644 | | - resource=resource, |
645 | | - context={"object_type": object_type.value, "object_id": object_id}, |
646 | | - ) |
647 | | - records = core.provenance.versions(object_type=object_type, object_id=object_id) |
648 | | - return JSONResponse( |
649 | | - {"versions": [record.model_dump(mode="json") for record in records]}, |
650 | | - headers=RELATIONSHIP_RESPONSE_HEADERS, |
651 | | - ) |
652 | | - |
653 | | - async def provenance_version(request: Request) -> Response: |
654 | | - _body, actor = await body_and_actor(request, core) |
655 | | - try: |
656 | | - object_type = ProvenanceObjectType(request.path_params["object_type"]) |
657 | | - except ValueError as exc: |
658 | | - raise ValidationError("provenance object type is invalid") from exc |
659 | | - raw_version = request.path_params["version"] |
660 | | - if not raw_version.isascii() or not raw_version.isdigit() or int(raw_version) < 1: |
661 | | - raise ValidationError("provenance version is invalid") |
662 | | - object_id = request.path_params["object_id"] |
663 | | - resource = f"provenance:{object_type.value}:{object_id}" |
664 | | - core._require( |
665 | | - actor=actor, |
666 | | - action="provenance.read", |
667 | | - resource=resource, |
668 | | - context={ |
669 | | - "object_type": object_type.value, |
670 | | - "object_id": object_id, |
671 | | - "version": int(raw_version), |
672 | | - }, |
673 | | - ) |
674 | | - record = core.provenance.get_version( |
675 | | - object_type=object_type, |
676 | | - object_id=object_id, |
677 | | - version=int(raw_version), |
678 | | - ) |
679 | | - return JSONResponse( |
680 | | - {"provenance": record.model_dump(mode="json")}, |
681 | | - headers=RELATIONSHIP_RESPONSE_HEADERS, |
682 | | - ) |
683 | | - |
684 | 551 | async def issue_task_grant(request: Request) -> Response: |
685 | 552 | body, actor = await body_and_actor(request, core) |
686 | 553 | parsed = TaskGrantIssueBody.model_validate_json(body) |
@@ -1461,19 +1328,14 @@ async def replay_version_events(request: Request) -> Response: |
1461 | 1328 | RELATIONSHIP_RESPONSE_HEADERS, |
1462 | 1329 | ) |
1463 | 1330 | ) |
| 1331 | + routes.extend( |
| 1332 | + create_provenance_routes( |
| 1333 | + core, |
| 1334 | + body_and_actor, |
| 1335 | + RELATIONSHIP_RESPONSE_HEADERS, |
| 1336 | + ) |
| 1337 | + ) |
1464 | 1338 | routes += [ |
1465 | | - Route("/v1/provenance/origins", register_provenance_origin, methods=["POST"]), |
1466 | | - Route("/v1/provenance/derivations", derive_provenance, methods=["POST"]), |
1467 | | - Route( |
1468 | | - "/v1/provenance/{object_type}/{object_id}", |
1469 | | - provenance_versions, |
1470 | | - methods=["GET"], |
1471 | | - ), |
1472 | | - Route( |
1473 | | - "/v1/provenance/{object_type}/{object_id}/{version}", |
1474 | | - provenance_version, |
1475 | | - methods=["GET"], |
1476 | | - ), |
1477 | 1339 | Route("/v1/task-grants", issue_task_grant, methods=["POST"]), |
1478 | 1340 | Route("/v1/task-grants/{grant_id}", get_task_grant, methods=["GET"]), |
1479 | 1341 | Route("/v1/task-grants/{grant_id}/revoke", revoke_task_grant, methods=["POST"]), |
|
0 commit comments