Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
27 changes: 23 additions & 4 deletions content/hub/_content.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,42 @@
{{- if partial "hub-open.html" . -}}
{{- .AddPage (dict "path" "." "kind" "section" "type" "hub" "title" "PipeLab Hub" "description" "Explore the PipeLab Hub for Pipelock components, setup instructions, documented limits, and links to the evidence supplied for each listing." "outputs" (slice "html" "markdown" "hubindex")) -}}
{{- $adapter := . -}}
{{- range slice "bundles" "configs" "recipes" "verifiers" -}}
{{- range slice "bundles" "configs" "recipes" "verifiers" "removed" -}}
{{- $adapter.AddPage (dict "path" . "kind" "section" "type" "hub" "title" (printf "Hub %s" .) "description" (printf "Browse Pipelock %s in the PipeLab Hub. Read setup instructions, supplied evidence, and documented limitations for each component." .) "outputs" (slice "html" "markdown")) -}}
{{- end -}}
{{- range $route, $facts := site.Data.hub.generated.sections -}}
{{- $path := strings.TrimSuffix "/" (strings.TrimPrefix "/hub/" $route) -}}
{{- if and $path (not (in (slice "bundles" "configs" "recipes" "verifiers" "removed") $path)) -}}
{{- $.AddPage (dict "path" $path "kind" "section" "type" "hub" "title" "Hub components" "description" "Browse Pipelock components in the PipeLab Hub. Read setup instructions, supplied evidence, and documented limitations for each component." "outputs" (slice "html" "markdown")) -}}
{{- end -}}
{{- end -}}
{{- $seen := newScratch -}}
{{- range site.Data.hub.generated.listings -}}
{{- /* Only trusted normalized records enter this adapter. No contributor
map is merged into frontmatter. Description uses type and ID only. */ -}}
{{- $listing := .listing -}}
{{- with .bundle_sha256 -}}
{{- if ne $listing.bundle_sha256 . -}}{{- errorf "hub bundle metadata digest differs" -}}{{- end -}}
{{- end -}}
{{- if .served_source -}}
{{- if ne (crypto.SHA256 (os.ReadFile .served_source)) .bundle_sha256 -}}{{- errorf "hub served bundle digest differs" -}}{{- end -}}
{{- end -}}
{{- $group := index (dict "bundle" "bundles" "config" "configs" "recipe" "recipes" "verifier" "verifiers") $listing.type -}}
{{- if not $group }}{{ errorf "hub record has unknown type" }}{{ end -}}
{{- if not (findRE `^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$` $listing.id) }}{{ errorf "hub record has invalid id" }}{{ end -}}
{{- $path := printf "%s/%s" $group $listing.id -}}
{{- if $seen.Get $path }}{{ errorf "hub duplicate listing path: %s" $path }}{{ end -}}
{{- $seen.Set $path true -}}
{{- $description := printf "Pipelock %s listing %s. Read setup instructions, supplied evidence, documented limitations, and the maintainer's external source links." $listing.type $listing.id -}}
{{- /* Description cap: AGENTS.md's 120–155 character SEO contract. */ -}}
{{- $description = strings.Truncate 155 "" $description -}}
{{- $path := printf "%s/%s" $group $listing.id -}}
{{- with .route -}}{{- $path = strings.TrimPrefix "/hub/" . -}}{{- end -}}
{{- $path = strings.TrimSuffix "/" $path -}}
{{- if $seen.Get $path }}{{ errorf "hub duplicate listing path: %s" $path }}{{ end -}}
{{- $seen.Set $path true -}}
{{- $.AddPage (dict "path" $path "kind" "page" "type" "hub" "title" $listing.title "description" $description "outputs" (slice "html" "markdown") "params" (dict "hub" .)) -}}
{{- end -}}
{{- range site.Data.hub.generated.references -}}
{{- $params := dict "hub" . -}}
{{- if eq .indexable false -}}{{- $params = merge $params (dict "robots" "noindex, follow") -}}{{- end -}}
{{- $.AddPage (dict "path" .path "kind" "page" "type" "hub" "title" .title "description" .description "outputs" (slice "html" "markdown") "params" $params) -}}
{{- end -}}
{{- end -}}
7 changes: 7 additions & 0 deletions data/hub/benchmark-method.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"format": 1,
"pairs": null,
"interleave": ["baseline", "target"],
"gomaxprocs": 1,
"measurement_policy": {"min_confidence": "low", "include_experimental": true}
}
1 change: 1 addition & 0 deletions data/hub/latency-limits.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"rule_ratio":null,"bundle_ratio":null,"deadline_ns":null}
46 changes: 46 additions & 0 deletions docs/hub-harness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Hub verification harness

The harness checks signed bundle bytes with the pinned Pipelock production loader and scanners. A second Ed25519 verifier checks the signature in Node. Reader facts, routes, generated records and measurement references are bound to their source bytes. The Hub remains closed until its separate opening requirements are met.

## Build and native tests

The build reads local Git objects and cached Go modules. It does not download a toolchain or dependencies. `scripts/hub/engine.json` pins the Pipelock tag, commit and Go toolchain; a mismatch fails the build. The build adds only the harness file to a disposable source export.

From this site checkout, with local `../pipelock` and `../pipelock-rules` checkouts containing the pinned revisions:

```sh
capture_dir=$(mktemp -d)
node scripts/hub/build-harness.mjs ../pipelock "$capture_dir" > "$capture_dir/build.json"
HUBCHECK_BIN=$(node -p "JSON.parse(require('node:fs').readFileSync(process.argv[1], 'utf8')).binary" "$capture_dir/build.json")
HUBCHECK_ENGINE_DIR=$(dirname "$HUBCHECK_BIN")
HUBCHECK_REPOSITORY=$(realpath ../pipelock)
HUBCHECK_RULES_REPOSITORY=$(realpath ../pipelock-rules)
export HUBCHECK_BIN HUBCHECK_ENGINE_DIR HUBCHECK_REPOSITORY HUBCHECK_RULES_REPOSITORY
node --test test/hub-harness.test.mjs
```

The native reader, scanner and rendered-site tests require these paths. Without them, those tests are skipped and provide no native coverage. The naming code also checks its Unicode and ICU versions against the committed tables.

## Workload and observed matches

The official workload binds the served bundle digest to a rules-repository revision containing the same signed bytes. Each nonblank producer line is an individual input with its original line number. Missing negatives for experimental rules may use the versioned site supplements; a missing stable-rule fixture fails. The clean-text snapshots have committed digests. Producer labels describe the fixture source; they do not establish scanner accuracy.

The `site:fixture-span-truncation-v1` generator walks positive fixture lines in order and takes the first match of Go's `(?i)` expression. It removes final runes until the span is nonempty and no longer matches, then repeats that seed with a trailing space. It checks both a doubled seed and the complete capped candidate for raw matches. A missing match, empty-matching pattern, empty seed or raw match created by repetition holds generation.

The byte ceilings come from the pinned source: the largest fetch-response cap among `claude-code`, `strict` and `hostile-model`, the `claude-code` preset's outbound request-body cap, and the native per-tool-definition text limit. Tool inputs must fit both the serialized `tools/list` envelope and the native text budget, including the fixed name or description and raw input-schema bytes. The builder checks the mirrored native limit against its pinned declaration. Workloads use the smaller of these ceilings and the effective measurement configuration limits returned by the production loader; both are recorded in the binding.

Each candidate is also run through the isolated production scanner. Its `production_target_match` records the observed outcome. Normalization and validators can make that outcome differ from raw regex matching. The record therefore claims a repeated incomplete fixture sample and a raw nonmatch, with the production outcome stated separately. It does not establish a production-scanner negative or worst-case behavior. An incomplete production scan fails generation.

The derivation records the fixture origin and digest, match offsets, seed, removed-rune count, size ceilings, effective byte lengths and text digest. Node checks the seed against those fixture offsets and the removed-rune count, then reconstructs the candidate and checks its digest and transport sizes against the native helper. The enclosing workload has its own generator identity, parameters and digest. Earlier prefix-generator inputs are a different workload and cannot reuse these bindings.

## Measurements

`scripts/hub/benchmark-report.mjs` derives the reader from the executable and bundle it actually measures. With no explicit diagnostic workload, it constructs the official workload from the pinned repositories. It times each declared non-deprecated rule in isolation and the whole bundle, interleaving the same workload against the baseline. Loaded-rule identities must match exactly before timing.

Artifacts include all samples, maxima, actual pair count, executed workload digest, staged bundle and configuration digests, engine identity and method. The native process snapshots the configuration alongside the verified bundle before scanning; the report rejects digests that differ from its bindings. Content-addressed artifacts can coexist when reruns produce different samples. Regeneration reuses only matching bindings and recomputes the verdict from the separate limits. A timeout or incomplete evidence cannot become a pass. Unset latency limits remain unassessed in report mode and fail acceptance; no default admission budget is supplied.

## Catalog admission

Routine generation requires a passing current measurement; report mode can retain failed or unassessed diagnostic verdicts. Community bundle verification and publisher facts use exactly one registered publisher selected by ID. Per-item publisher names and keys do not override the registry.

The lifecycle caller supplies removed records and accepted baseline routes to generation. Retained IDs and bundle names join the accepted `data/hub/generated/inventory.json` name set and remain reserved in the regenerated inventory. Removal routes use the same manifest path as active records.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
"site:capability-details": "node scripts/capability-detail-audit.mjs",
"site:audit": "node scripts/gauntlet-evidence-audit.mjs && node scripts/verify-playground-assurances.mjs && node scripts/capability-detail-audit.mjs && node scripts/site-audit.mjs",
"site:links": "node scripts/external-link-audit.mjs",
"indexnow:submit": "node scripts/indexnow-submit.mjs"
"indexnow:submit": "node scripts/indexnow-submit.mjs",
"hub:build-harness": "node scripts/hub/build-harness.mjs",
"hub:generate": "node scripts/hub/generate.mjs",
"hub:bench": "node scripts/hub/benchmark-report.mjs"
},
"dependencies": {
"pg": "^8.13.1"
Expand Down
19 changes: 19 additions & 0 deletions scripts/hub/bench-workload/clean-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"format": 1,
"hugo_version": "0.147.7",
"source_base": "338832693152dd2e9ec236704a3bfeb416e16530",
"fixture": "test/hub-harness.test.mjs",
"fixture_sha256": "9edf8ae1b538c0f40ff1dd0a8e6a6b1485c515fb75dfc54dbd4c5cee6c4acfcd",
"files": [
{
"file": "learn-mcp-security.md",
"sha256": "2a071d32874a23668cc88f93f53e7aaa7c6a8e4330738d428ae2d240fac1a8eb",
"origin": "site:built-mirror:learn-mcp-security.md"
},
{
"file": "hub-example-recipe.md",
"sha256": "f885779e43e72780f5c0e7e82b43e0dd60134ff5df384be32af259d3541549d4",
"origin": "site:built-mirror:hub-example-recipe.md"
}
]
}
53 changes: 53 additions & 0 deletions scripts/hub/bench-workload/clean/hub-example-recipe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Source: https://pipelab.org/hub/recipes/example-recipe/index.md

# Example recipe

ID: example-recipe

Read a component\'s setup instructions and documented limitations\.

## Maintainer

Example maintainer

example

License: Apache\-2\.0

## Setup

Inspect the configuration before starting\.

```
pipelock run --config <file>
```

## Limitations

This is a rendering fixture\.

## Not claimed

No runtime trust is established\.

## Evidence

Evidence not supplied.

## Disclosures

AI assisted: false

Fixture text

None declared\.

## External links

PipeLab doesn't review these external destinations.

source (example\.com): https\:\/\/example\.com\/source




Loading
Loading