Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ permissions:

jobs:
test:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
node-version: "24"
persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version-file: ".nvmrc"
package-manager-cache: false
# No install step: the package has no dependencies by design.
- run: npm run check
- run: npm pack --dry-run
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## 0.4.1 — 2026-11-12

Final use-readiness audit and runnable consumer pattern.

- Trace verification now rejects malformed outcome metadata and unknown record
fields even if the digest was recomputed. With a panel it also checks argument
shape and declared redaction. It still does not establish authenticity.
- Explicit invalid inference network options are no longer silently defaulted.
- `npm run consumer` invokes a pinned, allowlisted demo read handler, checks its
result and records a success trace. It is not a general executor or MCP server.
- `npm run test:package` packs and installs the actual artifact offline, testing
ESM exports, the installed CLI binary and the included consumer example.
- CI runs these checks on the exact supported Node version, uses current pinned
actions, disables credential persistence and fixes the Ubuntu image version.
- Distribution guide distinguishes an owned-app pilot, licensed npm release and
a future tested MCP adapter. Package name/scope availability is unverified.

Valid 0.4.0 panels and trace bytes are unchanged. Malformed traces previously
accepted by the partial verifier now fail. Extra outcome fields supplied to
`buildTrace` are rejected rather than silently discarded. License and npm
publication remain unchanged.

## 0.4.0 — 2026-11-12

Experimental foundation audit and onboarding pass.
Expand Down
7 changes: 5 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ npm run check
```

This runs unit/CLI tests, real loopback HTTP integration tests, panel validation
and the offline API walkthrough. CI runs the same command plus `npm pack
--dry-run`. All checks must pass before merging. The standalone `npm run corpus`
and the offline API walkthrough, runnable consumer and package smoke check. The
package check builds a tarball, installs it offline in a temporary project, then
checks its ESM exports, CLI binary and included consumer example. CI runs the
same command on the exact `.nvmrc` version. All checks must pass before merging.
The standalone `npm run corpus`
command intentionally exits 1 on the current baseline; its expected scores and
failure modes are asserted inside the passing test suite.

Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Hardwire describes an application's operations in a small JSON file called a
`read` or `payment`, and a declared confirmation requirement. An agent
integration can inspect that contract instead of guessing which UI to click.

**Status: 0.4.0 experimental foundation.** This Node.js library validates panels
**Status: 0.4.1 experimental foundation.** This Node.js library validates panels
and arguments, compiles MCP tool descriptions, proposes panels from static HTML,
and creates verifiable trace digests. It does **not** execute operations, provide
an MCP server, log anyone in, or enforce human approval. No React dependency.
Expand All @@ -24,6 +24,7 @@ git clone https://github.com/Automatron-workflows/hardwire.git
cd hardwire
node --version
npm run walkthrough
npm run consumer
npm test
```

Expand All @@ -32,8 +33,14 @@ password redaction, and scores a sample inference. `npm test` also starts a
short-lived server on the loopback interface. In a sandbox that forbids listening
sockets, run `npm run test:unit`; the integration suite must still pass in CI.

`npm run consumer` goes one step further: it maps `search_catalogue` to a known
application function, returns a matching demo product, checks the result and
records a successful trace. It runs offline on fake data. This is a runnable
integration pattern, not an MCP server or an authenticated deployment.

**Next:** [step-by-step experiments](docs/GETTING-STARTED.md),
[API reference](docs/API.md), or [adding a panel to your app](docs/INTEGRATION.md).
For adoption and packaging, see [distribution and first deployment](docs/DISTRIBUTION.md).

## What a panel looks like

Expand Down
10 changes: 7 additions & 3 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ const trace = buildTrace({
outcome: { status: 'unknown' },
actor: 'local-experiment', at: '2026-11-12T10:00:00.000Z'
});
verifyTrace(trace); // digest and basic record checks
verifyTrace(trace, { panel }); // also exact panel revision and port binding
verifyTrace(trace); // digest and strict record-shape checks
verifyTrace(trace, { panel }); // also panel binding, argument shape and redaction
```

`buildTrace` accepts a raw or normalized panel and a port ID or port object. It
Expand All @@ -60,7 +60,11 @@ SHA-256 digest string. No response body is recorded. All outcomes are assertions
by the caller; none are independently observed by this package.

`verifyTrace` returns false for a changed record or a mismatch with the supplied
panel. It does not establish identity, approval, execution, or authenticity.
panel. With a panel it validates the recorded argument shape, including required
fields, and requires `[redacted]` at declared write-only positions. Secret enums
are replaced by that marker for this check; original secrets cannot be recovered
or validated from the record. Unknown trace/outcome/port fields are rejected.
It does not establish identity, approval, execution, or authenticity.
It cannot reconstruct redacted values. Two otherwise identical records that
differ only in redacted secrets intentionally have the same digest.

Expand Down
17 changes: 17 additions & 0 deletions docs/AUDIT-2026-11-12.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,20 @@ npm publication stays disabled.

Compatibility: normalized defaults and digests change from 0.3.0. Preserve old
panels with old traces; see CHANGELOG.md before comparing revisions.

## Follow-up: use readiness, 0.4.1

The final pass reproduced four false-positive verification cases: recomputed
traces with a malformed result digest, numeric outcome code, unknown record field
or wrong argument type. The verifier now enforces the record shape and, when a
panel is supplied, argument types/required fields and secret-redaction markers.
Tests also cover accessor-bearing inputs without invoking their getters.

Explicit zero/null/false inference options no longer select silent defaults.
The new consumer example performs one actual application-function read against
fake data and checks the result. A packed-install smoke check runs in CI, which
also uses current SHA-pinned actions and the exact supported Node version.

The remaining adoption blockers are product boundaries, not failing tests:
license selection, an owned npm identity, and a real client adapter with scoped
application access. See DISTRIBUTION.md. None is claimed to be released already.
97 changes: 97 additions & 0 deletions docs/DISTRIBUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Distribution and first deployment

## What is ready now

0.4.1 is usable by the owner as a Node.js contract, validation, inference and
trace library. `npm run consumer` proves one fixed read operation can execute
through an application-owned handler. `npm run check` also installs the actual
packed artifact in a clean temporary project and exercises its exports and CLI.

It is not yet a product that can be connected to an agent client and operate
arbitrary websites. There is no transport, identity service or general executor.
Public GitHub visibility does not provide a reuse license: `UNLICENSED` and
`private: true` are deliberate release blockers, not installation bugs.

## First working deployment

Use one application we control and an existing backend operation. Do not start
by tagging every UI element, handling third-party credentials or building a registry.

1. Publish a reviewed panel for three useful read operations: search, fetch one
record, and read status. Keep auth tokens and private data out of the panel.
2. Copy the consumer pattern into the app's trusted backend. Map each stable port
ID to an existing service function; scope every read to the authenticated user.
Bind the accepted panel revision to deployment configuration.
3. Add a small MCP adapter using a pinned official SDK. Implement initialization,
`tools/list` with Hardwire descriptions, and `tools/call` with known handlers.
Use stdio for the first local client; introduce remote hosting only when needed.
Remote authentication and authorization are additional deployment work.
4. Connect one supported MCP client and complete actual user tasks. Record the
client, adapter/SDK version, app revision, failures and observed results.
5. Add exactly one reversible write after the read path works. Require explicit
authorization and approval bound to the user, port, arguments and panel digest.
Implement idempotency, a checked result and read-back in the application.
6. Test denied access, cross-user access, a changed panel, invalid input, timeout,
repeated calls and refused approval. Treat untrusted results as data.

Acceptance target for this owned-app pilot: at least 20 recorded read tasks with
checked results, all denial cases refused, and no duplicate effect under a retried
write. These are proposed targets, not measurements already achieved. This does
not replace the separate real-page inference evaluation in ROADMAP.md.

Login should use the app's established authentication flow and scoped session.
A declared login port is not a reason to collect passwords in prompts or traces.

## Release the library

1. **Choose the license.** The owner must choose the permissions granted to outside
users. Add the matching LICENSE file and package metadata. This document does
not select a license or grant those rights.
2. **Choose an owned npm scope.** Candidate: `@automatron-workflows/hardwire`.
Availability and ownership are unverified; the GitHub organization does not
automatically own that npm scope. Do not advertise `npm install hardwire`.
3. Update the package name and install examples, remove `private: true` only for
the release, run `npm run check`, and inspect `npm pack --dry-run` for unintended
files. Freeze canonicalization test vectors before interoperability claims.
4. Publish a versioned experimental release and tag it on GitHub. Verify installing
that exact version from npm in a clean project; do not rely only on the checkout.
5. For ongoing releases, configure npm trusted publishing from the specific
GitHub repository/workflow, with provenance and release checks. Account/scope
ownership and first-package setup must be resolved before this can work.
Keep release credentials out of the repository.

No publishing workflow is enabled by this audit. Publishing still requires the
license, package identity, account access and an explicit release action.

## Distribution to developers and agent users

| Audience | Deliverable | Evidence needed before promoting it |
| --- | --- | --- |
| Application developers | Licensed npm library, GitHub README and one small integration example | Fresh install and the owned-app pilot work end to end. |
| Agent users | Runnable MCP adapter with client setup instructions | Tested `tools/list` and `tools/call` in one real client. |
| Additional integrators | A concise case study and a reproducible failure report | Three independent teams can integrate without bespoke patches. |

The MCP Registry is a discovery layer for actual MCP servers; it does not host
the package or convert a JSON panel into a server. List the adapter only after
it exists and its artifact or remote endpoint is available. Do not list the
current core library as an operational MCP server.

Start with direct onboarding of three teams that own both an app and its agent
integration. Measure time to first successful task, integration code required,
task success, denied unauthorized calls and repeated use after one week. Publish
the measured before/after workflow and a short recording. Broader developer
announcements should link to that evidence and an installable artifact. Stars,
registry presence and a synthetic score are not adoption.

The initial promise should be narrow: **expose a few real application operations
as validated agent tools without teaching the agent to navigate the UI**. Avoid
claims of universal compatibility, automatic login or unmeasured speed gains.

## Sources checked on 2026-11-12

- [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/): OIDC-based
release authentication and provider configuration.
- [MCP Registry publishing quickstart](https://modelcontextprotocol.io/registry/quickstart):
metadata, underlying artifacts, identity verification and server publication.
- [MCP tools specification](https://modelcontextprotocol.io/specification/2025-11-25/server/tools):
tool discovery and calls. Core Hardwire implements descriptions only.
6 changes: 6 additions & 0 deletions docs/GETTING-STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ Run every command below from the repository root with Node 24.16+.
`npm run walkthrough` is the fastest complete offline tour. It makes no network
requests and needs no model or credentials.

To see a tool actually call an application function, run `npm run consumer`.
It calls `search_catalogue` with `{ "query": "lamp" }`, returns the fake
`Desk lamp` product and records a checked success. Read `examples/consumer.mjs`
to replace the fixed handler with your own authorized service. A model client
still needs a transport adapter; merely publishing a panel cannot make calls.

## 1. Inspect an explicit contract

```sh
Expand Down
13 changes: 12 additions & 1 deletion docs/INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ method, headers, CSRF handling, body serialization or session requirements.

## Consumer setup

Start with `npm run consumer` and [the runnable consumer](../examples/consumer.mjs).
It pins a reviewed panel digest, refuses unknown tools or changed panels,
validates arguments, invokes an allowlisted read handler, checks the application's
result and binds its digest into a trace. It handles only fake public catalogue
data and grants no account access. Handler failures propagate to the caller;
production error reporting and refusal/failure traces remain integration work.

A trusted Node consumer can use this explicit sequence:

1. Fetch the panel under your own access and network policy. Validate it.
Expand All @@ -38,7 +45,8 @@ A trusted Node consumer can use this explicit sequence:
7. Observe the result, build a trace, and retain the exact panel for verification.

The repository implements steps 2–4's format helpers and step 7's record helper.
It does not implement a generic runtime for steps 1, 5 or 6. Do not implement a
The consumer example demonstrates a single fixed handler for step 6. It does not
implement a generic runtime for steps 1, 5 or 6. Do not implement a
consumer as “fetch whatever endpoint the untrusted panel says.” Absolute HTTPS
endpoints can be cross-origin; a real consumer needs an explicit destination
allowlist and must never forward credentials automatically.
Expand All @@ -63,3 +71,6 @@ The WebMCP document explicitly identifies itself as a Community Group draft,
not a W3C Standard or a standards-track specification. Hardwire is an independent
experiment, not a competing web standard or an official extension of any of the
above. Its own discovery file and metadata vocabulary may change.

See [distribution and first deployment](DISTRIBUTION.md) for the concrete path
from this example to a client-connected pilot and an installable release.
10 changes: 8 additions & 2 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Foundation and next gates

## Foundation: implemented in 0.4.0
## Foundation: implemented in 0.4.1

- Strict panel and schema validation, argument checks and normalized digests.
- MCP tool descriptions with the same closed-object semantics as validation.
Expand All @@ -9,6 +9,7 @@
- Fixed-path discovery diagnostics with bounded network responses.
- Trace creation, redaction, verification and exact panel binding.
- Offline walkthrough, local HTTP demo, CLI/API guides and automated checks.
- An application-owned read-handler example and automated packed-install checks.

The library is ready for controlled experiments by the owner. It is not a
production executor or an open-source release. License selection is still open.
Expand Down Expand Up @@ -48,7 +49,9 @@ read-back without UI navigation. Every action must have a known handler,
authorization, explicit approval policy, idempotency behavior, a checked result
and a trace bound to the reviewed panel. Inject failures and retry scenarios.

The local HTTP demo currently proves discovery, inference and a read response.
The offline consumer proves one fixed read-handler mapping, result check and
trace. It has no authentication or mutation support and does not satisfy this
gate. The local HTTP demo proves discovery, inference and a read response.
It deliberately refuses POST. It does not satisfy the traversal gate.
Before adding a generic executor, define method/serialization/credential rules
and bind approval to exact arguments and panel revision. Prefer an explicit
Expand All @@ -63,6 +66,9 @@ external implementation contributions or promoting reusable packages.

## Release decisions still open

Follow [distribution and first deployment](DISTRIBUTION.md) for the ordered pilot,
package and client-adapter rollout. Publishing the panel alone cannot connect a client.

- Choose a license; `UNLICENSED` and `private: true` remain unchanged.
- Decide whether npm distribution is useful and check/reserve an appropriate name.
- Design browser/WebMCP integration only against a pinned, reviewed API version.
Expand Down
5 changes: 4 additions & 1 deletion docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ hash. Verification does not prove identity, execution or approval.
real UTC timestamp in the shown format (milliseconds optional). `actor` and
optional outcome `code` are non-empty strings of at most 128 characters. An
optional result digest must be `sha256:` plus 64 lowercase hex digits.
`verifyTrace(trace, { panel })` additionally checks exact panel and port binding.
`verifyTrace` rejects unknown record, port and outcome fields, malformed optional
outcome metadata and non-JSON records. `verifyTrace(trace, { panel })` additionally
checks exact panel and port binding, argument shape and `[redacted]` markers at
declared write-only positions. Original secret values cannot be verified.
Write-only array items are redacted too; unmarked secrets are not detected.

## 7. Canonical JSON
Expand Down
4 changes: 4 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Examples

Run `npm run consumer` for an application-owned read-handler integration. It
returns a fake catalogue product and records its checked result; see
`consumer.mjs`. `npm run walkthrough` demonstrates the format helpers offline.

| Path | What it is | Try it with |
| --- | --- | --- |
| `example-panel.json` | A complete panel for a fictional shop, including every effect class. | `validate`, `audit`, `compile`, `trace` |
Expand Down
Loading