httk.core.project

The httk project anchor and the core-owned httk project command.

A project is a directory marked at its root by a httk_project control directory, discovered by walking upward exactly as git finds a .git. This package owns that anchor — creating it, reading and validating its project.json, and managing its Ed25519 identity and trust anchors — and the core-only httk project command that operates on it. It creates no workflow workspace; that is layered on by a workflow installation.

The anchor API is re-exported here for convenience; the command and its implementation live in httk.core.project.cli.

Submodules

Attributes

PROJECT_DIRECTORY

PROJECT_FILE

PUBLIC_KEY_PREFIX

PROJECT_PRIVATE_KEY_RELATIVE_PATH

The exact private-key path created by the project identity implementation.

Exceptions

LegacyProjectError

Raised when discovery finds a legacy project directory.

Functions

canonical_public_key(value)

Normalize any accepted public key spelling to the recorded one.

discover_project([start])

Find the nearest project root, or refuse a legacy one, at or above start.

format_public_key(raw)

Return the recorded representation of one raw Ed25519 public key.

import_v1_project(root, *[, source, name])

Create the project anchor from a legacy ht.project directory.

initialize_project(root, *, name[, description, ...])

Initialize the project anchor: its metadata, its key, and its remotes dir.

key_fingerprint(value)

Return the stable display fingerprint of one public key.

parse_public_key(value)

Decode a recorded public key, accepting the bare base64 spelling too.

pin_project_key([root])

Adopt the project's current keys/project.pub as its trust anchor.

pinned_project_key(metadata)

Return the project's own pinned public key, or None when absent.

project_public_key_path(root)

Return where a project keeps its own signing key's public half.

read_project(root)

Read and validate the project.json of the project rooted at root.

read_project_section(root, name)

Return one named object member of project.json, empty when absent.

read_public_key_file(path)

Read one public-key file and return its recorded public key.

require_project([start])

Return the nearest project root, refusing when there is none.

trust_project_key(root, key)

Adopt one further public key as a trust anchor of this project.

trusted_project_keys(metadata)

Return every key metadata pins: the project's own and any adopted one.

write_project_section(root, name, value)

Store one named object member of project.json and return the metadata.

seal_project(out_path[, project_path])

Create a signed ZIP containing a project without private keys.

verify_seal(zip_path, *[, expect_key, trusted_keys])

Verify a sealed project ZIP and return signer information.

Package Contents

httk.core.project.PROJECT_DIRECTORY = 'httk_project'[source]
httk.core.project.PROJECT_FILE = 'project.json'[source]
httk.core.project.PUBLIC_KEY_PREFIX = 'ed25519:'[source]
exception httk.core.project.LegacyProjectError(message, *, root, kind)[source]

Bases: ValueError

Raised when discovery finds a legacy project directory.

Carries the offending directory as root and the legacy flavor as kind"v1" for an httk v1 ht.project directory, "prerelease" for a pre-release httk v2 .httk-project anchor — so a caller that deliberately handles one flavor (for example read-only verification of a v1 manifest) does not have to parse the message.

Parameters:
  • message (str) – Diagnostic explaining the legacy project and its remedy.

  • root (pathlib.Path) – Directory containing the legacy project marker.

  • kind (str) – Legacy flavor, either v1 or prerelease.

root
kind
httk.core.project.canonical_public_key(value)[source]

Normalize any accepted public key spelling to the recorded one.

Parameters:

value (str) – Accepted public-key text to normalize.

Returns:

Canonical prefixed public-key text.

Raises:

ValueError – If the public-key text is invalid.

Return type:

str

httk.core.project.discover_project(start=None)[source]

Find the nearest project root, or refuse a legacy one, at or above start.

Discovery walks from start and its parents, treating a file start as its containing directory. If it finds a legacy marker, the exception identifies the required remedy: run httk project import-v1 PATH for ht.project, or rename .httk-project to httk_project for the pre-release anchor.

Parameters:

start (str | os.PathLike[str] | None) – Directory or file from which to begin the upward search, or None for the current directory.

Returns:

Nearest project root, or None when no marker is found.

Raises:

httk.core.project.LegacyProjectError – If discovery finds a v1 or pre-release project marker.

Return type:

pathlib.Path | None

httk.core.project.format_public_key(raw)[source]

Return the recorded representation of one raw Ed25519 public key.

Parameters:

raw (bytes) – Raw public-key bytes to record.

Returns:

Canonical prefixed public-key text.

Raises:

ValueError – If the key is not 32 bytes long.

Return type:

str

httk.core.project.import_v1_project(root, *, source=None, name=None)[source]

Create the project anchor from a legacy ht.project directory.

Only the anchor is created: the project’s metadata and the adoption of the legacy identities its old manifests were signed with. A workflow installation adds the workspace and any queue import on top of this.

Parameters:
  • root (str | os.PathLike[str]) – Directory in which to create the new project anchor.

  • source (str | os.PathLike[str] | None) – Legacy project directory, or root/ht.project when omitted.

  • name (str | None) – Optional replacement project name.

Returns:

Imported project metadata.

Raises:
Return type:

dict[str, object]

httk.core.project.initialize_project(root, *, name, description='', manifest_exclusions=())[source]

Initialize the project anchor: its metadata, its key, and its remotes dir.

This creates only the anchor — httk_project with project.json, the project’s Ed25519 signing key, and the remotes directory. It creates no workflow workspace; a workflow installation layers that on top of the anchor so that a core-only installation still has a working project.

Parameters:
  • root (str | os.PathLike[str]) – Directory in which to create the project anchor.

  • name (str) – Human-readable project name.

  • description (str) – Optional project description.

  • manifest_exclusions (collections.abc.Iterable[str]) – Relative paths excluded from project manifests.

Returns:

Newly written project metadata.

Raises:

httk.core.project.LegacyProjectError – If root contains a v1 or pre-release project marker.

Return type:

dict[str, object]

httk.core.project.key_fingerprint(value)[source]

Return the stable display fingerprint of one public key.

Parameters:

value (str) – Public-key text whose fingerprint is calculated.

Returns:

Stable SHA-256 fingerprint text.

Raises:

ValueError – If the public-key text is invalid.

Return type:

str

httk.core.project.parse_public_key(value)[source]

Decode a recorded public key, accepting the bare base64 spelling too.

Parameters:

value (str) – Public-key text to decode.

Returns:

Raw public-key bytes.

Raises:

ValueError – If the algorithm, encoding, or key length is invalid.

Return type:

bytes

httk.core.project.pin_project_key(root=None)[source]

Adopt the project’s current keys/project.pub as its trust anchor.

Pinning is always an explicit act. Verification trusts the key recorded in project.json and never the key a manifest carries in its own header, so adopting the key that is in the tree right now is exactly the decision an operator has to make consciously for an older project that has no pin.

Parameters:

root (str | os.PathLike[str] | None) – Project root, or None to discover the nearest project.

Returns:

Updated project metadata.

Raises:

ValueError – If no project exists or its public key is invalid.

Return type:

dict[str, object]

httk.core.project.pinned_project_key(metadata)[source]

Return the project’s own pinned public key, or None when absent.

Parameters:

metadata (collections.abc.Mapping[str, object]) – Project metadata containing the optional public-key member.

Returns:

Canonical pinned key, or None when the metadata has no key.

Raises:

ValueError – If the pinned key is present but invalid.

Return type:

str | None

httk.core.project.project_public_key_path(root)[source]

Return where a project keeps its own signing key’s public half.

Parameters:

root (str | os.PathLike[str]) – Project root containing the anchor.

Returns:

Path to the project’s public key file.

Return type:

pathlib.Path

httk.core.project.read_project(root)[source]

Read and validate the project.json of the project rooted at root.

Parameters:

root (str | os.PathLike[str]) – Project root whose manifest is read.

Returns:

Validated project metadata.

Raises:

ValueError – If the manifest is not an httk project manifest.

Return type:

dict[str, object]

httk.core.project.read_project_section(root, name)[source]

Return one named object member of project.json, empty when absent.

A section is a top-level member of the project manifest that some layer above the anchor owns — the workflow workspace registry, a campaign map — and reads and writes as a whole. The anchor does not interpret the member; it only guarantees that what a caller stores under a name comes back as the object it was, and refuses a member that some other writer has left as a non-object so a caller never silently reads a scalar as a mapping.

Parameters:
  • root (str | os.PathLike[str]) – Project root whose manifest is read.

  • name (str) – Top-level manifest member to retrieve.

Returns:

A copy of the named object, or an empty object when absent.

Raises:

ValueError – If the named manifest member is not an object.

Return type:

dict[str, object]

httk.core.project.read_public_key_file(path)[source]

Read one public-key file and return its recorded public key.

Parameters:

path (str | os.PathLike[str]) – Public-key file to read.

Returns:

Canonical public-key text from the first line.

Raises:

ValueError – If the file cannot be read, is empty, or contains an invalid key.

Return type:

str

httk.core.project.require_project(start=None)[source]

Return the nearest project root, refusing when there is none.

Parameters:

start (str | os.PathLike[str] | None) – Directory or file from which to begin the upward search, or None for the current directory.

Returns:

Nearest project root.

Raises:
Return type:

pathlib.Path

httk.core.project.trust_project_key(root, key)[source]

Adopt one further public key as a trust anchor of this project.

Parameters:
  • root (str | os.PathLike[str] | None) – Project root, or None to discover the nearest project.

  • key (str) – Public key to add to the project’s trusted anchors.

Returns:

Updated project metadata.

Raises:

ValueError – If no project exists, the key is invalid, or trusted_keys is invalid.

Return type:

dict[str, object]

httk.core.project.trusted_project_keys(metadata)[source]

Return every key metadata pins: the project’s own and any adopted one.

The pinned key of project.json is the trust anchor a manifest is checked against. trusted_keys carries the additional anchors an operator has adopted deliberately — most often the legacy identities an imported httk v1 project signed its old manifests with.

Parameters:

metadata (collections.abc.Mapping[str, object]) – Project metadata whose trust anchors are read.

Returns:

Unique canonical project and adopted trust anchors.

Raises:

ValueError – If trusted_keys is not a string array or contains an invalid key.

Return type:

tuple[str, Ellipsis]

httk.core.project.write_project_section(root, name, value)[source]

Store one named object member of project.json and return the metadata.

The write is an ordinary read-modify-write of the validated manifest, so the members the anchor owns are preserved untouched and only the named section is replaced. The section must be a mapping; the anchor stores its members verbatim without interpreting them.

Parameters:
Returns:

Updated project metadata.

Raises:

ValueError – If the named section is not a mapping.

Return type:

dict[str, object]

httk.core.project.PROJECT_PRIVATE_KEY_RELATIVE_PATH = 'httk_project/keys/project.seed'[source]

The exact private-key path created by the project identity implementation.

httk.core.project.seal_project(out_path, project_path=None)[source]

Create a signed ZIP containing a project without private keys.

The path and suffix exclusions are primary. The content guard catches exact and re-encoded copies of known private material; transformed or truncated secrets are outside that guard’s scope.

Parameters:
  • out_path (str | pathlib.Path) – Destination ZIP path.

  • project_path (str | pathlib.Path | None) – Project root, or None to discover the nearest project.

Returns:

The destination path.

Raises:

ValueError – If the project is unsafe to seal or its identity is invalid.

Return type:

pathlib.Path

httk.core.project.verify_seal(zip_path, *, expect_key=None, trusted_keys=())[source]

Verify a sealed project ZIP and return signer information.

Parameters:
Returns:

A JSON-ready verification report.

Raises:

ValueError – If the ZIP, manifest, files, tree digest, or signature is invalid.

Return type:

dict[str, object]