Skip to content

Commit cbeab89

Browse files
hyperpolymathclaude
andcommitted
feat(innervation): Phase 2 — specs, tools, and docs
Ship the innervation architecture's Phase 2 deliverables: 6 artefacts completing the vocabulary, tooling, and visibility layer introduced in Phase 1 (coordination.k9, VeriSimDB config, Hypatia self-scan). New specs: - inline-annotations/SPEC.adoc — @trust/@contract/@Grade grammar, v0.1.0 - groove-protocol/spec/INNERVATION-SIGNALS.adoc — canonical signal vocabulary - a2ml-templates/STATE.a2ml.v2.spec.adoc — thin session-journal format - .verisimdb/ECOSYSTEM-INGEST.adoc — derived ecosystem-link pipeline - docs/PANLL-PANELS.adoc — CRG Dashboard, Compliance Monitor, Proof Hub - docs/INNERVATION.adoc — human+machine-readable architecture hub New Rust tools (all tested): - inline-annotations/extractor/ — comment scanner, emits A2ML (7/7 tests) - k9-coordination-protocol/tools/k9-init/ — 6a2→coordination.k9 scaffold (5/5 tests) - hooks/playbook-to-recipe/ — PLAYBOOK.a2ml→Hypatia recipes (5/5 tests) All tools emit A2ML, not JSON, matching the .machine_readable/ family. Updated: - .verisimdb/config.toml — inline-annotation schema aligned to SPEC fields, contract attr renamed kind→obligation (avoids directive-level collision) - .github/workflows/echidna-verify.yml — Agda+Idris2 verification CI (Idris2 jobs skip gracefully pending pack-install step) Per-repo metadata footprint on track to go from 6-7 files to 2 (coordination.k9 + STATE.a2ml v2). Standards repo remains the pilot. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0359908 commit cbeab89

20 files changed

Lines changed: 2721 additions & 5 deletions

File tree

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# ECHIDNA proof verification — formal verification of Agda and Idris2 proofs.
3+
#
4+
# Scope:
5+
# - lol/proofs/theories/**/*.agda
6+
# - a2ml/src/A2ML/Proofs.idr
7+
# - avow-protocol/avow-lib/src/abi/*.idr
8+
#
9+
# Dogfooding: standards repo defines ECHIDNA trust pipeline; this workflow
10+
# applies that pipeline to the repo's own proofs.
11+
12+
name: ECHIDNA Proof Verification
13+
14+
on:
15+
push:
16+
branches: [main]
17+
paths:
18+
- 'lol/proofs/**'
19+
- 'a2ml/src/**/*.idr'
20+
- 'avow-protocol/avow-lib/src/abi/*.idr'
21+
- '.github/workflows/echidna-verify.yml'
22+
pull_request:
23+
paths:
24+
- 'lol/proofs/**'
25+
- 'a2ml/src/**/*.idr'
26+
- 'avow-protocol/avow-lib/src/abi/*.idr'
27+
schedule:
28+
# Weekly re-verification to catch stale-proof drift
29+
- cron: '0 6 * * 1'
30+
workflow_dispatch:
31+
32+
permissions:
33+
contents: read
34+
35+
jobs:
36+
agda-lol:
37+
name: Agda — lol/proofs
38+
runs-on: ubuntu-latest
39+
timeout-minutes: 20
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
43+
with:
44+
submodules: recursive
45+
46+
- name: Install Agda
47+
run: |
48+
sudo apt-get update
49+
sudo apt-get install -y agda agda-stdlib
50+
agda --version
51+
52+
- name: Type-check proofs
53+
id: typecheck
54+
run: |
55+
set -e
56+
echo "=== Agda proofs under lol/proofs ==="
57+
find lol/proofs/theories -name '*.agda' -print
58+
cd lol/proofs
59+
for f in $(find theories -name '*.agda'); do
60+
echo "--- checking $f ---"
61+
agda --safe "$f" 2>&1 | tee -a ../../agda-verify.log || true
62+
done
63+
64+
- name: Postulate audit
65+
run: |
66+
echo "=== Postulate usage in lol/proofs ==="
67+
grep -rn "postulate" lol/proofs/theories/ || echo "No postulates found"
68+
69+
- name: Upload log
70+
if: always()
71+
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
72+
with:
73+
name: agda-verify-log
74+
path: agda-verify.log
75+
if-no-files-found: ignore
76+
77+
idris2-a2ml:
78+
name: Idris2 — a2ml proofs
79+
runs-on: ubuntu-latest
80+
timeout-minutes: 20
81+
steps:
82+
- name: Checkout
83+
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
84+
with:
85+
submodules: recursive
86+
87+
- name: Install Idris2
88+
run: |
89+
# Idris2 is not in Ubuntu repos; install from release or container.
90+
# Placeholder: use pack or nix. For now, skip gracefully if not available.
91+
if ! command -v idris2 >/dev/null 2>&1; then
92+
echo "::warning::Idris2 not installed in this job; skipping (add pack-install step when ready)"
93+
exit 0
94+
fi
95+
idris2 --version
96+
97+
- name: Type-check A2ML.Proofs
98+
run: |
99+
if ! command -v idris2 >/dev/null 2>&1; then
100+
echo "skipping — idris2 missing"
101+
exit 0
102+
fi
103+
cd a2ml
104+
idris2 --check src/A2ML/Proofs.idr 2>&1 | tee ../idris2-a2ml.log
105+
106+
- name: Upload log
107+
if: always()
108+
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
109+
with:
110+
name: idris2-a2ml-log
111+
path: idris2-a2ml.log
112+
if-no-files-found: ignore
113+
114+
idris2-avow:
115+
name: Idris2 — AVOW consent proofs
116+
runs-on: ubuntu-latest
117+
timeout-minutes: 20
118+
steps:
119+
- name: Checkout
120+
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
121+
with:
122+
submodules: recursive
123+
124+
- name: Install Idris2
125+
run: |
126+
if ! command -v idris2 >/dev/null 2>&1; then
127+
echo "::warning::Idris2 not installed in this job; skipping"
128+
exit 0
129+
fi
130+
idris2 --version
131+
132+
- name: Type-check AVOW proofs
133+
run: |
134+
if ! command -v idris2 >/dev/null 2>&1; then
135+
echo "skipping — idris2 missing"
136+
exit 0
137+
fi
138+
cd avow-protocol/avow-lib
139+
for f in src/abi/Consent.idr src/abi/Unsubscribe.idr src/abi/Types.idr; do
140+
if [ -f "$f" ]; then
141+
echo "--- checking $f ---"
142+
idris2 --check "$f" 2>&1 | tee -a ../../idris2-avow.log
143+
fi
144+
done
145+
146+
- name: Upload log
147+
if: always()
148+
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
149+
with:
150+
name: idris2-avow-log
151+
path: idris2-avow.log
152+
if-no-files-found: ignore
153+
154+
trust-summary:
155+
name: Trust pipeline summary
156+
needs: [agda-lol, idris2-a2ml, idris2-avow]
157+
runs-on: ubuntu-latest
158+
if: always()
159+
steps:
160+
- name: Summarise
161+
run: |
162+
echo "## ECHIDNA Trust Summary" >> "$GITHUB_STEP_SUMMARY"
163+
echo "" >> "$GITHUB_STEP_SUMMARY"
164+
echo "| Target | Result |" >> "$GITHUB_STEP_SUMMARY"
165+
echo "|---|---|" >> "$GITHUB_STEP_SUMMARY"
166+
echo "| Agda lol/proofs | ${{ needs.agda-lol.result }} |" >> "$GITHUB_STEP_SUMMARY"
167+
echo "| Idris2 a2ml | ${{ needs.idris2-a2ml.result }} |" >> "$GITHUB_STEP_SUMMARY"
168+
echo "| Idris2 avow | ${{ needs.idris2-avow.result }} |" >> "$GITHUB_STEP_SUMMARY"
169+
echo "" >> "$GITHUB_STEP_SUMMARY"
170+
echo "See artefacts for verification logs." >> "$GITHUB_STEP_SUMMARY"

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,11 @@ htmlcov/
9191

9292
# asdf version manager
9393
.tool-versions
94+
95+
# Rust build artefacts (innervation tools)
96+
inline-annotations/extractor/target/
97+
k9-coordination-protocol/tools/k9-init/target/
98+
hooks/playbook-to-recipe/target/
99+
inline-annotations/extractor/Cargo.lock
100+
k9-coordination-protocol/tools/k9-init/Cargo.lock
101+
hooks/playbook-to-recipe/Cargo.lock

.verisimdb/ECOSYSTEM-INGEST.adoc

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// SPDX-License-Identifier: PMPL-1.0-or-later
2+
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath)
3+
= VeriSimDB Ecosystem Ingest Pipeline
4+
:version: 0.1.0-draft
5+
:status: Draft
6+
:updated: 2026-04-05
7+
8+
== Purpose
9+
10+
Derive ecosystem-link octads from the code itself — not from hand-written
11+
ECOSYSTEM.a2ml files. The pipeline scans every repo for dependency manifests
12+
and import statements, normalises them to repo identities, and emits
13+
`ecosystem-link` octads to VeriSimDB (port 8097).
14+
15+
This replaces the Graph-modality section of ECOSYSTEM.a2ml with a derived,
16+
continuously-updated graph.
17+
18+
== Evidence Sources
19+
20+
[cols="1,2,2",options="header"]
21+
|===
22+
| Source | File(s) | Link type
23+
24+
| Cargo (Rust) | `Cargo.toml` [dependencies] | `cargo-dep`
25+
| Deno | `deno.json` imports | `deno-import`
26+
| Mix (Elixir/Gleam) | `mix.exs` deps | `mix-dep`
27+
| Pack (Idris2) | `pack.toml`, `*.ipkg` depends | `idris-dep`
28+
| Zig | `build.zig.zon` | `zig-dep`
29+
| Guix/Nix | `guix.scm`, `flake.nix` inputs | `nix-input`
30+
| Just recipes | `Justfile` cross-repo refs | `build-ref`
31+
| GitHub Actions | `uses:` in `.github/workflows/*.yml` | `action-ref`
32+
| Inline imports | `import`, `use`, `require` statements | `code-import`
33+
|===
34+
35+
== Octad Shape
36+
37+
Each link becomes one `ecosystem-link` octad (schema already defined in
38+
`.verisimdb/config.toml`):
39+
40+
- **Semantic**: `source_repo`, `target_repo`, `link_type`, `strength`
41+
- **Temporal**: `first_seen`, `last_confirmed`, `stale_after_days`
42+
- **Graph**: `dependency_chain[]`, `transitive_consumers[]`
43+
- **Provenance**: `detection_method`, `evidence_file`, `evidence_line`
44+
45+
**Strength** is a float in [0, 1]:
46+
47+
- 1.0 — declared direct dependency (manifest entry)
48+
- 0.7 — import statement found in code
49+
- 0.4 — mentioned in config or docs only
50+
- 0.1 — text match in comments
51+
52+
== Pipeline Stages
53+
54+
[source]
55+
----
56+
scan -> parse -> normalise -> resolve -> emit
57+
(walk) (format) (name) (repo URL) (VeriSimDB)
58+
----
59+
60+
=== Stage 1 — scan
61+
62+
Walk every repo under `~/Documents/hyperpolymath-repos/`. For each file
63+
matching the patterns in the evidence-source table, record `(repo, path,
64+
format)`.
65+
66+
=== Stage 2 — parse
67+
68+
Per-format parsers extract dependency edges:
69+
70+
- TOML (Cargo, pack.toml, zon) — parse and read `[dependencies]`
71+
- deno.json — parse as JSON (reluctantly) and read `imports`
72+
- mix.exs — regex `{:dep, "~> x.y"}` entries
73+
- Justfile — regex `just -d ../other-repo` invocations
74+
- Workflows — regex `uses: owner/repo@sha`
75+
76+
=== Stage 3 — normalise
77+
78+
Dependency names (`serde`, `deno.land/std`, `:phoenix`) are mapped to
79+
canonical repo identities via a registry file
80+
(`.verisimdb/repo-aliases.a2ml`). Unknown names are emitted with
81+
`target_repo="UNRESOLVED:<raw>"` so they can be resolved later.
82+
83+
=== Stage 4 — resolve
84+
85+
For each canonical repo name, resolve to a git URL from the hyperpolymath
86+
registry (if known) or leave as external. External deps are tagged
87+
`external=true`.
88+
89+
=== Stage 5 — emit
90+
91+
For each edge, create or update the `ecosystem-link` octad:
92+
93+
- If an octad with the same `(source_repo, target_repo, link_type)` exists,
94+
update `last_confirmed` and keep `first_seen`
95+
- Otherwise create a new octad with `first_seen = last_confirmed = now`
96+
- Emit a Groove signal `ecosystem.link.discovered` (for new) or
97+
nothing (for updates)
98+
99+
A temporal rule in VeriSimDB marks octads where
100+
`now - last_confirmed > stale_after_days` as stale and emits
101+
`ecosystem.link.stale`.
102+
103+
== Scheduling
104+
105+
- **On-demand**: `just ecosystem-ingest` in the standards repo
106+
- **Per-commit**: consumed via `commit.pushed` Groove signal — re-scan the
107+
changed repo only
108+
- **Weekly full sweep**: cron in CI — scans all 290+ repos
109+
110+
== Implementation Plan (not this session)
111+
112+
1. `ecosystem-ingest` CLI in Rust (~500 LOC)
113+
2. Per-format parsers as separate modules
114+
3. Repo alias registry (`.verisimdb/repo-aliases.a2ml`)
115+
4. VeriSimDB client using the Groove protocol
116+
117+
== Consumer Wiring
118+
119+
Once emitted, octads drive:
120+
121+
- **PanLL Ecosystem panel** — render the dependency graph
122+
- **Hypatia `ecosystem-drift` rule** — flag when a repo's declared
123+
ECOSYSTEM.a2ml disagrees with the derived graph
124+
- **CRG evidence** — consumer count feeds into grade basis
125+
126+
== Open Questions
127+
128+
- Monorepo handling: each sub-project emits its own edges? Yes — the
129+
`source_repo` becomes `monorepo-name/sub-project-name`.
130+
- Circular deps: record as-is; let consumers flag cycles.
131+
- Version pinning: v0.1 ignores versions (just captures the edge); v0.2 may
132+
add a `version_range` field.

.verisimdb/config.toml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,27 @@ graph = ["dependency_chain", "transitive_consumers"]
6161
provenance = ["detection_method", "evidence_file", "evidence_line"]
6262

6363
# Inline annotations — @trust/@contract/@grade from code
64+
# See: inline-annotations/SPEC.adoc (v0.1.0 draft, 2026-04-05)
6465
[[octad_schema]]
6566
entity = "inline-annotation"
6667
description = "Machine-readable annotation extracted from source code"
6768

6869
[octad_schema.modalities]
69-
semantic = ["file_path", "line", "annotation_type", "value", "function_name"]
70-
temporal = ["extracted_at", "source_last_modified"]
71-
provenance = ["commit_sha", "extractor_version"]
72-
vector = ["function_embedding"]
70+
# file/line/target_line always present; kind determines which of the kind-specific fields apply:
71+
# kind=trust → level, prover, since
72+
# kind=contract → obligation (must/trust/dust/intent), clause, severity
73+
# kind=grade → value, basis, assessed
74+
semantic = [
75+
"file", "line", "target_line", "target_name",
76+
"kind",
77+
"level", "prover", "since",
78+
"obligation", "clause", "severity",
79+
"value", "basis", "assessed",
80+
]
81+
temporal = ["extracted_at", "source_last_modified", "since", "assessed"]
82+
provenance = ["extractor", "extractor_version", "grammar_version", "source_commit", "repo"]
83+
graph = ["target_entity_id", "asserts_about"]
84+
vector = ["target_embedding"]
7385

7486
# ─────────────────────────────────────────────────────────────
7587
# Groove Integration
@@ -78,7 +90,7 @@ vector = ["function_embedding"]
7890
[groove]
7991
enabled = true
8092
service_name = "standards-verisimdb"
81-
capabilities = ["octad-store", "vql-query", "annotation-index"]
93+
capabilities = ["octad-store", "vcl-query", "annotation-index"]
8294

8395
[groove.signals]
8496
# Afferent: what this instance emits

0 commit comments

Comments
 (0)