httk.core.project.members

The on-disk registry of a project’s members, and the handler protocol.

A member is a self-contained subtree a project holds whose internals another module owns — a workflow workspace is the first one. The project records only that a member of a given kind lives at a given path; everything about what the member contains, how it is sealed, and how it is checked is delegated to the handler that module registers for the kind (see httk.core.register.members).

Core owns the verbs — seal, manifest, repair, verify — and this on-disk registry that tells those verbs which subtrees to hand off and to whom. It interprets a member no further than its path and kind.

Attributes

Classes

ProjectMember

One member a project holds: a subtree of a given kind.

ProjectMemberHandler

What core needs from the module that owns one member kind.

Functions

members_path(project_root)

Return where a project's member registry lives.

project_members(project_root)

Return the members registered in a project, in recorded order.

register_project_member(project_root, path, kind, *[, ...])

Record that a member of kind lives at path, idempotently.

unregister_project_member(project_root, path)

Remove the member recorded at path.

update_project_member_path(project_root, old, new)

Move the member recorded at old to new, keeping its kind.

set_project_member_name(project_root, path, name)

Set (or clear) the recorded name of the member at path.

Module Contents

httk.core.project.members.MEMBERS_FORMAT = 'httk-project-members'[source]
httk.core.project.members.MEMBERS_FORMAT_VERSION = 1[source]
class httk.core.project.members.ProjectMember[source]

One member a project holds: a subtree of a given kind.

Parameters:
  • path – The member’s posix relpath below the project root ("." is the project root itself).

  • kind – The member kind, whose handler owns the member’s internals.

  • name – The member’s recorded name, or None when it has none.

path: str[source]
kind: str[source]
name: str | None = None[source]
class httk.core.project.members.ProjectMemberHandler[source]

Bases: Protocol

What core needs from the module that owns one member kind.

Every method takes the member’s own root — project_root / member.path — rather than the project, so a handler never has to rediscover where it lives. The manifest, repair, and verify verbs core owns call exactly these; a member seals through its own module, and core only records the resulting digest.

manifest_exclusions(project_root, member_relpath)[source]

Return the manifest exclusions this member contributes.

These are fnmatch patterns on posix relpaths below the project root (not the member root): the member decides which of its own internals — control directories, working scratch — the project manifest must leave out, while its payload files stay covered.

Parameters:
  • project_root (pathlib.Path) – The project root the patterns are relative to.

  • member_relpath (str) – This member’s relpath below the project root.

Returns:

The exclusion patterns this member contributes.

Return type:

tuple[str, Ellipsis]

seal_digest(member_root)[source]

Return this member’s identifier and the SHA-256 of its seal bytes.

The digest is what a project seal records for the member, so a project seal transitively pins the member without re-hashing its payload.

Parameters:

member_root (pathlib.Path) – This member’s root directory.

Returns:

The member identifier and the hex SHA-256 of its seal file.

Raises:

httk.core.project.sealing.SealError – If the member is unsealed.

Return type:

tuple[str, str]

verify(member_root, *, trusted_keys, deep)[source]

Verify this member and return its report entries.

Each entry is a mapping in the whole-tree verification shape — level, subject, valid, verdict, reason, signers, missing_signers, and discrepancies (a list of {kind, path}) — so the project report concatenates a member’s entries with its own.

Parameters:
  • member_root (pathlib.Path) – This member’s root directory.

  • trusted_keys (collections.abc.Sequence[str]) – Trust anchors to classify the signers against.

  • deep (bool) – Whether to recurse into every seal the member references.

Returns:

The member’s verification entries.

Return type:

tuple[dict[str, object], Ellipsis]

repair(member_root, *, apply)[source]

Repair this member, or report only, returning its findings.

Each finding is a mapping in the repair shape — check, status, message, repairable, repaired, action, details — so they concatenate with core’s own anchor findings. Repairs are applied by default; apply=False is a dry run that mutates nothing.

Parameters:
  • member_root (pathlib.Path) – This member’s root directory.

  • apply (bool) – Whether to apply repairs; False reports only.

Returns:

The member’s repair findings.

Return type:

tuple[dict[str, object], Ellipsis]

scan_project(project_root, *, apply, adopt)[source]

Optionally scan the whole project for members of this kind.

Core calls this once per registered kind at project scope, whether or not any member of the kind is registered, so a handler can surface members present on disk but missing from members.json — the exact rescue an empty registry needs. Repairs are applied by default; apply=False is a dry run that mutates nothing, and adopt tells the scan whether to also (re)establish members’ machine-local links on this machine. It is optional: core invokes it only when the handler defines it. Findings use the same mapping shape as repair().

Parameters:
  • project_root (pathlib.Path) – The project root to scan.

  • apply (bool) – Whether to apply repairs; False reports only.

  • adopt (bool) – Whether to adopt members of this kind on this machine.

Returns:

The project-scope findings for this kind.

Return type:

tuple[dict[str, object], Ellipsis]

adopt(member_root, *, name)[source]

Optionally (re)establish this member’s local links on this machine.

Adoption is the act of rebuilding whatever per-user or machine-local links a member needs to be usable here — for example, httk-workflow registers the member’s workspace in the per-user name registry under its recorded name. It is idempotent and never mutates sealed state. Core invokes it only when the handler defines it, passing the member’s recorded name; findings use the same mapping shape as repair().

Parameters:
  • member_root (pathlib.Path) – This member’s root directory.

  • name (str | None) – The member’s recorded name, or None when it has none.

Returns:

The adoption findings for this member.

Return type:

tuple[dict[str, object], Ellipsis]

guard(member_root)[source]

Return a context manager fencing the member while it is snapshotted.

A member that must be quiescent to be described faithfully — a workspace with running jobs — returns a guard that acquires that quiescence and raises if it cannot. A member with nothing to fence returns contextlib.nullcontext().

Parameters:

member_root (pathlib.Path) – This member’s root directory.

Returns:

A context manager held around the snapshot.

Return type:

contextlib.AbstractContextManager[object]

httk.core.project.members.members_path(project_root)[source]

Return where a project’s member registry lives.

Parameters:

project_root (str | os.PathLike[str]) – The project root whose member registry path to build.

Returns:

The httk_project/members.json path.

Return type:

pathlib.Path

httk.core.project.members.project_members(project_root)[source]

Return the members registered in a project, in recorded order.

A missing registry is an empty project, not an error.

Parameters:

project_root (str | os.PathLike[str]) – The project root whose members to read.

Returns:

The registered members.

Raises:

ValueError – If the registry file is malformed.

Return type:

tuple[ProjectMember, Ellipsis]

httk.core.project.members.register_project_member(project_root, path, kind, *, name=None)[source]

Record that a member of kind lives at path, idempotently.

The path is normalized to a posix relpath below the project root and a path outside the project is refused. Registering the same path again replaces its kind and name.

Parameters:
  • project_root (str | os.PathLike[str]) – The project root whose registry to update.

  • path (str | os.PathLike[str]) – The member’s path, absolute or relative to the project root.

  • kind (str) – The member kind whose handler owns the member.

  • name (str | None) – The member’s recorded name, or None for none.

Returns:

The members after the update.

Raises:
Return type:

tuple[ProjectMember, Ellipsis]

httk.core.project.members.unregister_project_member(project_root, path)[source]

Remove the member recorded at path.

Parameters:
  • project_root (str | os.PathLike[str]) – The project root whose registry to update.

  • path (str | os.PathLike[str]) – The member’s path, absolute or relative to the project root.

Returns:

The members after the removal.

Raises:
Return type:

tuple[ProjectMember, Ellipsis]

httk.core.project.members.update_project_member_path(project_root, old, new)[source]

Move the member recorded at old to new, keeping its kind.

Parameters:
  • project_root (str | os.PathLike[str]) – The project root whose registry to update.

  • old (str | os.PathLike[str]) – The member’s current path, absolute or relative to the root.

  • new (str | os.PathLike[str]) – The member’s new path, absolute or relative to the root.

Returns:

The members after the move.

Raises:
Return type:

tuple[ProjectMember, Ellipsis]

httk.core.project.members.set_project_member_name(project_root, path, name)[source]

Set (or clear) the recorded name of the member at path.

Parameters:
  • project_root (str | os.PathLike[str]) – The project root whose registry to update.

  • path (str | os.PathLike[str]) – The member’s path, absolute or relative to the project root.

  • name (str | None) – The name to record, or None to clear it.

Returns:

The members after the update.

Raises:
Return type:

tuple[ProjectMember, Ellipsis]