Touchstone
Stack-aware repository audit loops, locally or in GitHub Actions
Touchstone turns agent findings into reviewable, PR-only changes.
PyPI · Install · GitHub Actions · Architecture · Report issue
Features
- Stack detection before configuration — identifies stable package-backed Targets and composes
generic,javascript,node,typescript,react,nextjs,python,fastapi,django,rust, anddotnetProfiles from repository evidence. - Monorepo-aware scope — discovers npm, pnpm, Yarn, Bun, uv, Poetry, and PDM evidence, records a package manager per Target, tracks dependency edges, and validates a changed Target plus its dependents.
- Owned configuration — keeps deliberate settings in
touchstone.tomland reproducible stack evidence in.touchstone/generated.toml; Profile refresh never replaces project overrides. - Structured validation — runs argv-based gates in bounded Target directories with timeouts, scrubbed subprocess environments, hook-free locked preparation, and tracked-file mutation checks. Generated commands use the Target's own package manager. A Profile enables only side-effect-minimal Gates; every command that runs project code stays a disabled Candidate until the project override accepts it.
- Three execution backends — runs from native launchd/systemd wake signals, a generated repository-owned GitHub Actions workflow, or one container per repository.
- One project, many repositories — a project file holds the Loops, engines, and schedules that are the same everywhere;
touchstone syncrenders a fleet-owned fragment each member repository extends and overrides, and proposes it as a pull request rather than writing it. - Split hosted trust stages — separate Prepare, Analysis, Verify, mutation-only Publish, and Snapshot jobs give each stage one credential domain, and mint the repository-scoped App token only after an independent stage has validated the candidate.
- Reproducible hosted runtime — one credential-free Action step installs hash-locked Python dependencies, the exact Agent CLI named by the committed
npmlockfile, and the project's own locked dependencies, then attests that environment to the repository HEAD, configuration, Targets, and lockfiles. - PR-only lifecycle — low-risk approved candidates open ready pull requests; higher-risk or rejected candidates open drafts. Auto-merge is off unless a Loop enables it, and then only where Verify is independent.
- Durable recovery — transactional Due Slot claims, encrypted state snapshots, stable run outcomes, explicit change states, and exact-candidate resume decisions survive retries, missed wake signals, and a Publish job that dies mid-publication.
Tech Stack
| Runtime | Python 3.12+ · LangGraph · SQLite |
| Agents | Codex CLI · Claude Code CLI |
| Stack model | Declarative TOML Profiles · Targets |
| Local backend | launchd on macOS · systemd user timers on Linux |
| Hosted backend | GitHub Actions · owner-controlled GitHub App · AES-256-GCM artifacts |
| Quality | pytest · Ruff · Hatchling · isolated-wheel acceptance tests |
Project Structure
src/touchstone/
├── profiles/ Safe detection, workspace discovery, and materialization
├── resources/profiles/ Nine built-in declarative stack Profiles
├── hosted/ Workflow, crypto, runtime stages, and GitHub App setup
├── scheduling/ Portable schedules, durable Due Slots, launchd, systemd
├── nodes/ Audit, classify, independent review, and publication
├── engines/ Codex and Claude execution contracts
├── execution/ Local and SSH command runners
├── validation.py Structured preparation and Validation Gates
├── lifecycle.py PR publication, reconciliation, reaping, and resume
├── config.py Versioned, project-neutral configuration
└── cli.py Installed command surface
action.yml Pinned composite Action with five explicit stages
action-requirements.lock Hash-locked Python runtime for the composite Action
agent-runtime/ Integrity-locked Codex and Claude CLI runtimes
docs/adr/ Architecture decisions
tests/fixtures/acceptance/ Next.js, Django, and mixed-monorepo wheel fixtures
Getting Started
Install Touchstone, then rehearse one loop inside a GitHub repository you are authorised to audit:
pipx install touchstone-agent
cd /path/to/your/repository
touchstone init --backend local
touchstone profile detect
touchstone config check
touchstone harness resolve
touchstone doctor
touchstone setup --dry-run
touchstone setup
touchstone doctor
touchstone run code --dry-run
touchstone init --backend local finds the Git root, GitHub slug, default branch, package managers, workspace Targets, and stack Profiles. A Target ID comes from the package name in package.json or pyproject.toml, with a repository-relative path hash for collisions and unnamed Targets. Local initialization asks only for the engine, model, and Loop schedule; GitHub Actions visibility and wake cadence are not local-backend decisions. It writes an embedded Harness declaration plus the project-owned and generated configuration files. The rehearsal runs the configured model and validation path but does not publish.
Prerequisites — Python 3.12+, pipx, Git, authenticated gh, and an authenticated Codex or Claude CLI. Native scheduling is supported on macOS and Linux.
For non-interactive initialization, provide every decision explicitly:
touchstone init --backend local --non-interactive \
--engine codex \
--model YOUR_MODEL_ID \
--schedule weekly@SUN,03:00 \
--timezone Australia/Sydney
Use --backend actions, --workflow, --visibility, and --wake-minutes only for hosted execution.
Documentation
- Operator and design context
- Generated loop graph
- Architecture Decision Records
- Stack Profiles and Actions design
- Example project configuration
- Example generated configuration
- Security policy
GitHub Actions
The hosted backend is generated into the repository being audited. The repository owns its triggers, permissions, concurrency, secret mappings, retention, and immutable Action references.
touchstone actions init
touchstone actions init --check
git add .github/workflows/touchstone.yml touchstone.toml .touchstone/generated.toml
git commit -m "ci: add touchstone audit loop"
actions init resolves the release tag matching the installed touchstone-agent version — v0.1.2 is the currently published release — to a 40-character commit SHA, so the generated workflow pins the revision this CLI documents rather than a moving branch. Automation may pass an audited revision with --action-sha, and must when a development or release-candidate build is installed. --check is read-only and exits 3 when the committed workflow has drifted.
[!WARNING]
touchstone actions setupopens GitHub twice: first to review and create an owner-controlled GitHub App, then to install it for only the selected repository. Read the owner, repository, repository scope, and permissions on both GitHub pages before confirming. The one-time private key is piped directly togh secret set; Touchstone never writes it to disk.
Run the guided setup from a trusted local terminal:
touchstone actions setup
gh secret set OPENAI_API_KEY --app actions
touchstone actions setup --check
touchstone doctor
For Claude, set ANTHROPIC_API_KEY instead. Organization-owned repositories use touchstone actions setup --organization, which creates the App under the organization and stores its secrets as organization secrets restricted to the selected repository. If loopback callback delivery is unavailable, use touchstone actions setup --manual-code and paste the one-time manifest code at the hidden prompt. Setup uses the one-time App private key in memory to verify the live installation, selected-repository scope, and permissions before storing the key as an Actions secret, then zeroes its memory buffer. It records only a non-secret attestation and gives an explicit replacement-key command when the one-time key can no longer be recovered.
Later touchstone actions setup --check and touchstone doctor can inspect only that cached attestation because Touchstone deliberately does not retain the private key. Doctor therefore reports a warning, not a live pass; a successful hosted Publish token-mint is the current end-to-end proof that the App installation still works.
The standard repository secrets are:
| Secret | Available to |
|---|---|
OPENAI_API_KEY or ANTHROPIC_API_KEY |
Analysis only |
TOUCHSTONE_APP_ID and TOUCHSTONE_APP_PRIVATE_KEY |
Publish only |
TOUCHSTONE_STATE_KEY |
Analysis, Verify, Publish, and Snapshot |
[!NOTE] The whole hosted backend has now run on GitHub Actions runners, end to end: the composite Action and its hash-locked install, the Agent CLI installed from its committed lock, the per-stage credential boundaries, the artifact round-trip between jobs, the state artifact named by the configuration digest, restoring that snapshot on a later run, and all five stages — Prepare, Analysis, Verify, Publish and Snapshot — reaching their recorded outcomes. One run analyzed a real defect, validated the candidate under repository read only, minted an installation token from an Owner App, and opened a labelled pull request authored by the App. Recovery from a Publish that fails partway is covered by tests but has not been exercised against a real interrupted run.
The workflow has only schedule and workflow_dispatch triggers. It does not run on pull requests. Public repositories default to off-hour 15-minute wake signals; private repositories default to one off-hour wake per hour. Configure a supported interval with actions.wake_minutes, then rerun touchstone actions init. Each wake evaluates durable schedules, so frequent wake signals do not imply frequent model calls.
Each job runs the composite Action's credential-free install step first. That step maps no secret at all: it installs the hash-locked Python runtime, the locked Agent CLI, and the project's locked dependencies, then writes a non-secret attestation binding them to the repository HEAD, configuration digest, Target set, and lockfiles. A later stage reuses that exact environment; a mismatched or absent attestation fails closed unless the process still holds no model credential, so dependencies are only ever installed before model credentials exist.
| Stage | Model credential | Publishing credential | Repository token | State key |
|---|---|---|---|---|
| Prepare | no | no | read | no |
| Analysis | yes | no | no | yes |
| Verify | no | no | read | yes |
| Publish | no | App token | App token | yes |
| Snapshot | no | no | no | yes |
Prepare restores the latest encrypted state envelope without a decryption key. Analysis decrypts state, claims one Due Slot, runs the model, and emits an authenticated, candidate-named artifact whose unique ID binds the stable finding, base SHA, patch digest, and run. Verify runs on a separate runner that holds no model credential and no publishing credential; it does receive a repository read token and the state-decryption key. It checks repository, effective non-secret configuration, Profile digest, independently exported Loop and candidate lineage, base SHA, patch digest, health gates, and Validation Gates in a disposable worktree, then emits a versioned attestation. Publish starts on another clean runner, reconstructs the exact candidate from its authenticated artifact, checks the attestation, mints a short-lived App token scoped to the current repository, and performs only publication. Hosted commits are authored by the publishing App's own bot identity rather than the runner's synthesized one. git.author names which of the two identities — that bot or the configured operator — git records as the author; the other is credited in a Co-Authored-By trailer. Configure no operator and nothing is credited, which is what a configuration without the setting already did. Snapshot has neither model nor publishing credentials. It finalizes the Due Slot, retains state under the full configuration digest for 90 days by default, and — when Publish failed or was cancelled without recording an outcome — reconstructs a failed partial marker from the authenticated candidate so the next run is blocked until touchstone reconcile inspects that exact branch.
Locked preparation and Validation Gates run as subprocesses with a scrubbed environment — an allowlist of locale, path, and cache variables, a throwaway HOME, and no inherited credential — so project code never sees the state key or any token. Model processes get a separate allowlist carrying only that engine's own credential. Health checks are the deliberate exception: they call gh and therefore do use the repository read token, which is why Verify holds one.
Hosted operator decisions use the exact candidate ID:
gh workflow run touchstone.yml -f candidate_id=CANDIDATE_ID -f decision=approve
gh workflow run touchstone.yml -f candidate_id=CANDIDATE_ID -f decision=close
gh workflow run touchstone.yml -f candidate_id=CANDIDATE_ID -f decision=reanalyze
GitHub disables scheduled workflows after 60 days without activity in a public repository. touchstone doctor reports a disabled workflow and warns once the latest push is 45 days old; workflow_dispatch remains the explicit recovery path.
Configuration and Profiles
touchstone init writes schema v2. An existing schema-v1 configuration keeps loading unchanged — including one at ~/.config/touchstone/config.toml — and upgrading is an explicit command, never something a Touchstone upgrade performs on its own. A v1 deployment that is already running does not need to migrate to keep working.
Schema v2 splits ownership across two files:
touchstone.tomlis project-owned. It holds repository identity, engine, schedule, Actions policy, Loop choices, and explicit overrides..touchstone/generated.tomlis machine-owned. It records package/Profile versions, source digest, per-Target package managers, Targets, evidence, dependencies, protected/source paths, and validation candidates..touchstone/profiles/*.tomlmay add repository-local declarative Profiles. Profile files cannot import or execute project code.
A Loop's brief names the concern, and the Profile supplies the technology. The built-in concern briefs — builtin:hardcode, builtin:naming, builtin:error-handling, and builtin:test-coverage, beside the broader builtin:code-audit and builtin:harness-review — name no language or framework at all, so one brief serves every stack instead of one brief per stack per concern. A Profile declares its naming conventions as data in a [naming] table; profile refresh renders the conventions of a Target's whole Profile Set into the generated Loop context, and the naming brief reads them from there. A placeholder the project never fills resolves to a default stating that this project declares none, rather than reaching the session as literal $naming.
Detection distinguishes confirmed evidence, candidates requiring explicit confirmation, and unsupported version ranges. Floating or unresolvable framework versions remain candidates instead of being treated as confirmed. Repository-local declarative Profile detectors participate in the same bounded detection pass. In non-interactive mode, unresolved candidates or ambiguous lockfile families stop initialization instead of guessing. Select deliberately with --profile NAME or --package-manager NAME.
touchstone profile detect --json
touchstone profile diff
touchstone profile refresh --check
touchstone profile refresh --write
touchstone validate code
profile refresh --check and profile diff are read-only and exit 3 on drift. --write replaces only generated configuration, removes stale auto-detected Profiles, retains Profiles explicitly declared in the project-owned Target override, keeps an existing Target ID bound to its configured repository-relative path, and re-adopts a nested standalone project that the configuration already names. Enable a generated Validation Gate in that override after reviewing its argv, capability, preparation, timeout, and working directory.
Only git diff --check — a read-only check that runs no project code — is enabled without review. Everything else, including npm run test and npx tsc, is materialized as a disabled Candidate; a repository-local Profile cannot enable one either. Generated commands follow the package manager recorded for that Target, so a pnpm Target gets pnpm run test and pnpm exec tsc, a Bun Target gets bun run test and bun x tsc, and Yarn gets yarn run for both. A gate with preparation = "locked-install" runs one hook-free install per ecosystem before the gate itself:
| Package manager | Locked preparation |
|---|---|
npm |
npm ci --ignore-scripts |
pnpm |
pnpm install --frozen-lockfile --ignore-scripts |
yarn (classic) |
yarn install --frozen-lockfile --ignore-scripts |
yarn (Berry) |
yarn install --immutable --mode=skip-build |
bun |
bun install --frozen-lockfile --ignore-scripts |
uv |
uv sync --frozen --no-install-workspace --no-build |
pdm |
PDM_ONLY_BINARY=:all: pdm sync --frozen-lockfile --no-self |
Berry is detected from .yarnrc.yml or a packageManager major version of 2 or above. Poetry has no switch that guarantees a hook-free install, so a hook-free Poetry gate reports policy-unsupported and blocks instead of installing; set allow_build_hooks = true on that gate to accept poetry install and its project build hooks.
Any subtable of [engine] other than budget is a named pool member, and loop.<name>.engine chooses one; the unnamed [engine] is the member called default, so a configuration that names no second engine keeps its current meaning. A member carries its own model, endpoint, effort, budget, and api_key_env — the variable its credential arrives in — because two members can speak the same API and hold different keys. api_key_ref records where the operator's own secret store holds that key; Touchstone never reads it, and doctor prints the command that would. A member whose named variable is absent fails rather than falling back to the vendor's own key, which would send that credential to the member's endpoint. The generated workflow maps each member's secret into the Analysis job alone.
Set engine.base_url to send model calls to a self-hosted or third-party endpoint. Claude-shaped endpoints receive it as ANTHROPIC_BASE_URL; Codex receives a named provider, and engine.wire_api must stay responses because Codex no longer loads a configuration naming chat-completions. The address must be https unless it is loopback, and carries no query string or credentials — the key still travels in the environment.
Unknown configuration keys fail closed. Relative paths resolve from the configuration file. Secrets do not belong in TOML; secret-shaped SSH environment keys are rejected. When state_dir is omitted, Touchstone uses an isolated per-repository directory under $XDG_STATE_HOME/touchstone or ~/.local/state/touchstone.
Inspect exactly what Touchstone loaded before a run:
touchstone --version
touchstone config path
touchstone config check
touchstone config show
touchstone config show --effective --json
touchstone config explain harness.mode
path, check, show, and explain are read-only. Effective JSON represents every field as { "value": ..., "source": ... }; environment overrides are named as environment:TOUCHSTONE_*. Invalid configuration exits 78; blocked resolution or drift exits 3.
Upgrade an unversioned configuration to v1, then explicitly preview and apply v2:
touchstone config migrate touchstone.toml
touchstone config migrate-v2 touchstone.toml --timezone UTC --hourly-minute 0 --check
touchstone config migrate-v2 touchstone.toml --timezone UTC --hourly-minute 0 --write
Both migrations write a sibling backup before replacing project configuration. V2 migration refuses to overwrite an existing generated file. Stack Profiles, per-Target Validation Gates, and the GitHub Actions backend require v2; local scheduling, run, run-due, and resume do not.
Harness selection
Exactly one project Harness is selected for every explicitly configured run. User-level collaboration and machine-safety rules remain a baseline, not a second project Harness. Personal repositories normally embed their generated contract:
[harness]
mode = "embedded"
entrypoint = "AGENTS.md"
An organisation repository can instead name a canonical external Harness and immutable Git ref without committing a machine path:
[harness]
mode = "external"
source = "Efficient-Pty-Ltd/efficient-harness"
ref = "origin/main"
entrypoint = "harness/00-INDEX.md"
Register the checkout only on the machine that runs Touchstone:
touchstone harness register Efficient-Pty-Ltd/efficient-harness --path /local/checkout
touchstone harness list
touchstone harness resolve
touchstone harness unregister Efficient-Pty-Ltd/efficient-harness
Resolution verifies the Git remote identity, fetches the named remote, materializes a read-only snapshot from the resolved commit, and records that revision. It never reads uncommitted external Harness rules. Existing v1/v2 configurations without [harness] retain legacy repository-instruction discovery.
Projects Across Repositories
One project can cover many repositories. The project file lives in its own repository, so changing it is a reviewed pull request:
touchstone sync --project projects/personal.toml --check
touchstone sync --project projects/personal.toml --pr
touchstone sync --project projects/personal.toml --checkouts harness.local.toml --check
--check is read-only and exits 3 when a member differs from what the project renders. --pr opens one pull request per drifted member. There is no direct-write path: the configuration file is the root of Touchstone's permission model, so something able to edit it unattended could enable a Validation Gate for itself.
A portable member may use checkout = "misoto22-site" instead of path. --checkouts harness.local.toml resolves it from a machine-local file containing only [checkouts] and absolute paths. Exactly one of path or checkout is required; a missing logical checkout reports checkout-not-installed.
Each member's touchstone.toml names the rendered fragment and overrides anything it disagrees with:
version = 2
generated = ".touchstone/generated.toml"
extends = ".touchstone/fleet.toml"
Precedence runs from machine-owned evidence, through the fleet's shared decisions, to the repository's own word. Overriding one key leaves its siblings alone, so a member correcting a model keeps its engine name. A project may not set target, generated, project, state_dir, or version — target carries Validation Gate authorization, and that decision stays with the repository it endangers. A credential-shaped key that is not an op:// reference is refused, because a value written centrally reaches every member it renders to. See touchstone-project.example.toml.
Self-Hosted Containers
touchstone sync --compose docker-compose.yml renders one service per member repository. Each container sees one checkout, one state volume, and one credential set, because a single container iterating every repository would be central execution under another name.
touchstone sync --project projects/personal.toml --compose docker-compose.yml
docker compose up -d
The image carries Touchstone, git, gh, and the Agent CLI installed from its committed lockfile — and nothing a project owns. No image can hold every version of every toolchain a repository's Validation Gates need, and one supported stack does not run on Linux at all, so a repository needing a toolchain derives from the image:
FROM ghcr.io/misoto22/touchstone:0.1.2
RUN apt-get update && apt-get install -y --no-install-recommends <toolchain>
Scheduling reuses run-due unchanged: the container supervisor is a fixed-interval wake signal, not a second clock, because run-due already claims its Due Slot and coalesces missed periods. A failed wake is a failed run, not a failed supervisor — and it says so: every wake reports its exit code, and an exception that would otherwise be swallowed to keep the container alive is named in the log. The container's log is the only thing an operator can see, so nothing in it is buffered. Credentials arrive as injected environment variables listed in an uncommitted secrets/<service>.env; the rendered Compose file names the variables and carries no value and no reference. Auto-merge is unavailable on this backend, for the reason any backend without an independent Verify stage is refused.
Scheduling and Recovery
Loops accept hourly@MM, daily@HH:MM, or weekly@DAY,HH:MM in the configured IANA timezone. DST is resolved from local wall-clock intent.
touchstone install-scheduler --dry-run
touchstone install-scheduler
touchstone scheduler-status
touchstone run-due
The scheduler is only a Wake Signal. run-due transactionally claims a repository-global Due Slot, coalesces missed periods, runs at most one active change at a time, and retries retryable failures up to three times with bounded backoff. The same evaluator is used locally and in GitHub Actions.
status is pure and never mutates lifecycle state. Use reconcile when you intentionally want to compare recorded candidates with GitHub and record merged, closed, failed, or reaped transitions. A partial publication is resolved only once the pull request actually carries the Loop and escalation labels a complete publication applies; reconcile adds a missing label itself and leaves the record unresolved when it cannot:
touchstone status --json
touchstone reconcile --json
Local parked checkpoints print this contract:
touchstone resume <thread-id> approve|close|reanalyze
Approval reruns health and publication gates and refuses a pull request whose reviewed head changed. Close records an operator decision. Reanalyze closes the old candidate and starts from current default-branch state.
Stable exit codes are 0 for completed/no-change/rehearsed, 1 for failed, 3 for blocked or detected drift, and 78 for invalid configuration.
Safety Boundary
Touchstone owns configuration validation, bounded discovery, isolated worktrees, model orchestration, deterministic risk escalation, encrypted checkpoints, append-only lifecycle events, Due Slot claims, and pull-request transitions.
The target repository owns its tests, branch protection, required checks, deployment verification, audit policy, credentials, and final merge. Touchstone creates pull requests; it does not merge them. It does not install remote Profiles, resolve mutable Agent CLI versions at runtime, accept a GitHub App installation whose permissions exceed the documented map, request a broad personal access token, trigger from pull requests, or treat missing/malformed model output as a clean run.
A Loop may set auto_merge = true, which is the only path where a model's output reaches the default branch without a person reading it. It is configured per Loop, never per project, because a Loop removing an unused import and one reworking error handling carry risks that differ by orders of magnitude. Arming requires every condition to hold at publication time: low risk, an approving independent review, a pull request that is not a draft, passing Validation Gates, a repository that allows auto-merge, at least one declared required workflow, and a protected base branch. Any unmet condition leaves the pull request for a person and records which condition it was — including a forge that refused to arm the merge, which is otherwise the hardest kind of silence to diagnose. Beyond the switch, a Loop configures how the merge happens: auto_merge_strategy (squash, merge, or rebase, checked against what the repository permits by doctor rather than discovered at publication), auto_merge_delete_branch, auto_merge_window (["MON-THU,09:00-17:00", "FRI,09:00-12:00"] in the configured timezone — it bounds when the merge is armed, not when the forge completes it), and auto_merge_max_files, above which the change waits for a person. Configuring any of these without auto_merge = true is refused: it reads as a policy and behaves as a pull request that waits forever. A backend without an independent Verify stage — today, anything other than GitHub Actions — refuses such a Loop with policy-unsupported before pushing a branch, rather than silently opening an ordinary pull request.
A dry run prevents publication, not model access. It still runs the configured locked preparation and the Validation Gates of every Target the change reaches. Gate selection uses the recorded dependency graph: the Targets owning the changed paths plus their dependents, widened to every Target the Loop configures whenever a shared or repository-root change cannot be attributed safely. Use only repositories, hosts, models, GitHub accounts, and credentials you are authorised to use. Never include secrets, private repository content, model transcripts, encrypted-state keys, or unredacted diagnostics in public issues.
Report vulnerabilities privately through GitHub Security Advisories.
Development and Release
git clone https://github.com/Misoto22/touchstone.git
cd touchstone
uv sync --extra dev
uv run pytest
uv run ruff check .
uv run ruff format --check src tests
uv run touchstone graph --check
uv build
uv run twine check dist/*
The current published release is v0.1.2 on touchstone-agent on PyPI; the release candidate is v0.1.3. GitHub Releases publish through PyPI trusted publishing; the repository stores no PyPI API token.
See CONTRIBUTING.md for the TDD and pull-request workflow and CHANGELOG.md for user-facing changes.
Apache License 2.0 · LICENSE
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file touchstone_agent-0.1.3.tar.gz.
File metadata
- Download URL: touchstone_agent-0.1.3.tar.gz
- Upload date:
- Size: 4.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87238ea2f92fcdaa7ad627dba0c162109740fb5af03566e52cf5aa861e30f51b
|
|
| MD5 |
c9bb8bb450a54ded70becf29cfa86e51
|
|
| BLAKE2b-256 |
ceeb47574b7175354eec91c2db00bc679084b9cff6bf8db16fe13a178f99db59
|
Provenance
The following attestation bundles were made for touchstone_agent-0.1.3.tar.gz:
Publisher:
release.yml on Misoto22/touchstone
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
touchstone_agent-0.1.3.tar.gz -
Subject digest:
87238ea2f92fcdaa7ad627dba0c162109740fb5af03566e52cf5aa861e30f51b - Sigstore transparency entry: 2683065912
- Sigstore integration time:
-
Permalink:
Misoto22/touchstone@97e06e8bf4ea31b5e173f8f718a31acc8226665f -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/Misoto22
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@97e06e8bf4ea31b5e173f8f718a31acc8226665f -
Trigger Event:
release
-
Statement type:
File details
Details for the file touchstone_agent-0.1.3-py3-none-any.whl.
File metadata
- Download URL: touchstone_agent-0.1.3-py3-none-any.whl
- Upload date:
- Size: 238.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60e3ffc026831c880b18527e4cfe61f57b07042964d9222df4335f1de3ae162b
|
|
| MD5 |
497a506155fb173dca0928efb28350fd
|
|
| BLAKE2b-256 |
7bc4914041387b1d957b64561bbda5065f57dcd942a842b94ed6b03de96ccdce
|
Provenance
The following attestation bundles were made for touchstone_agent-0.1.3-py3-none-any.whl:
Publisher:
release.yml on Misoto22/touchstone
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
touchstone_agent-0.1.3-py3-none-any.whl -
Subject digest:
60e3ffc026831c880b18527e4cfe61f57b07042964d9222df4335f1de3ae162b - Sigstore transparency entry: 2683065942
- Sigstore integration time:
-
Permalink:
Misoto22/touchstone@97e06e8bf4ea31b5e173f8f718a31acc8226665f -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/Misoto22
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@97e06e8bf4ea31b5e173f8f718a31acc8226665f -
Trigger Event:
release
-
Statement type: