diff --git a/CONTINUATION.md b/CONTINUATION.md new file mode 100644 index 0000000..c393e86 --- /dev/null +++ b/CONTINUATION.md @@ -0,0 +1,70 @@ +# Continuing IICP development + +IICP is licensed and documented so that independent parties can review, +implement and continue the protocol without access to the original maintainer's +private development methods or production systems. + +## Start here + +1. Read [`GOVERNANCE.md`](GOVERNANCE.md), [`SPEC_STATUS.md`](SPEC_STATUS.md) and + [`VERSIONING.md`](VERSIONING.md). +2. Use [`ecosystem/public-repositories.json`](ecosystem/public-repositories.json) + to locate the authoritative specification and maintained implementations. +3. Reproduce the checks in [`CONTRIBUTING.md`](CONTRIBUTING.md) and + [`SPEC_RELEASE_PROCESS.md`](SPEC_RELEASE_PROCESS.md). +4. Use [`research/RESEARCH.md`](research/RESEARCH.md) for product decisions, + rejected alternatives and open evidence gaps. Research is informative unless + a specification explicitly makes it normative. +5. Use [`standards/REVIEWING.md`](standards/REVIEWING.md) for an independent + standards review or Internet-Draft candidate review. + +## What an independent implementation needs + +The versioned specifications, registries, JSON schemas, fixtures and +conformance runner are the interoperability contract. The Rust, Python and +TypeScript SDKs are useful implementation evidence, but no one implementation +may silently redefine the protocol. The PHP and Rust directory repositories +implement the control plane and have separate release lifecycles. + +An implementation should declare the protocol and profile versions it supports, +fail safely on unsupported required behavior and preserve the documented +privacy and security boundaries. Cross-language agreement within this project +is parity evidence, not independent adoption. + +## Forks and stewardship + +The Apache-2.0 license permits independent use and forks under its terms. A fork +does not automatically become the canonical IICP specification, inherit the +IICP name, control existing package registries or gain access to production +credentials. Those are distinct technical, governance, trademark and account +questions. + +While the current repository remains maintained, propose protocol changes in a +public issue and pull request. If it becomes unavailable, a successor effort +should preserve immutable release history, publish its governance and security +contacts, document the divergence point, retain compatibility fixtures and +avoid reusing released version numbers for different semantics. Competing forks +should use explicit implementation or profile identifiers until governance and +interoperability converge. + +Maintainer or standards-editor authority should be based on sustained public +review and implementation work, not access to private tools. A governance +transition must identify the repositories, release-signing authority, registry +accounts and security-reporting channel being transferred. No protocol artifact +should contain the credentials or recovery secrets needed for that transfer. + +## Standards work + +An Internet-Draft contribution is governed by the IETF process and IETF Trust +terms in addition to this repository's license. Building a review bundle or +discussing the protocol does not authorize a submission, create IETF consensus +or request an IANA registration. Any future registration request must identify +the responsible public specification, change controller and review policy. + +## Public/private boundary + +Technical research that led to a product or protocol decision belongs in the +public record with enough method and evidence to reproduce the conclusion. +Private prompts, orchestration, work-selection systems and personal meta-tools +are not implementation dependencies. The complete boundary is documented in +[`docs/governance/public-artifact-boundary.md`](docs/governance/public-artifact-boundary.md). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe06863..7b74b25 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,9 +18,10 @@ remove unsupported claims, add the concrete evidence, or keep clear wording when the warning does not apply in context. Coordinated releases must update `ecosystem/releases.json` with their wire, -conformance, compatibility, upgrade, migration and rollback semantics. The -private integration repository validates that record against component -manifests, tags and public registries. +conformance, compatibility, upgrade, migration and rollback semantics. Public +release evidence must be reproducible from component manifests, immutable tags +and public package registries. Private project tooling may run additional +checks, but it is not part of the public acceptance contract. Implementation bugs belong in the owning repository listed in `IMPLEMENTATIONS.md`. Never include production credentials, private topology or @@ -35,11 +36,29 @@ real task data. operator preview until its separate cutover gates pass. - Use the owning SDK or browser-node repository for language- or runtime-specific defects. -- Use `iicp.network` for cross-component integration, adoption, governance, - production evidence and private website or operations work. +- Use this repository for cross-component interoperability questions that + cannot be assigned to one implementation. Send private deployment or account + matters to `community@iicp.network`, without credentials or task content. When responsibility moves between repositories, create one sanitized canonical successor, link both issues and close the old issue as moved. Do not transfer a private issue directly into a public repository: its comments may contain private operational context. Closing preserves the historical record and does not mean that the successor work is complete. + +## Standards contributions and intellectual property + +Specification contributions remain subject to the repository license. Text +prepared for an Internet-Draft may also be submitted under the current IETF +Trust Legal Provisions and IETF Note Well. A contribution does not authorize a +standards submission. Contributors must disclose known intellectual-property +claims that would affect implementation or standardization and must not submit +text they are not entitled to license. + +The public record preserves technical evidence, alternatives and decisions. +Private development prompts, orchestration, work-selection systems and +meta-tools are not contribution requirements and must not be copied into this +repository. See +[`docs/governance/public-artifact-boundary.md`](docs/governance/public-artifact-boundary.md). +Independent implementers and successor maintainers should also read +[`CONTINUATION.md`](CONTINUATION.md). diff --git a/IMPLEMENTATIONS.md b/IMPLEMENTATIONS.md index 18054be..531ef14 100644 --- a/IMPLEMENTATIONS.md +++ b/IMPLEMENTATIONS.md @@ -2,15 +2,12 @@ This index is generated from `ecosystem/repositories.json`. Repositories are independently versioned; they are logical members of the IICP ecosystem, not -Git submodules. Visibility describes source access, not protocol maturity. +Git submodules. Private operations, website and development-method sources are +not public build, conformance or governance dependencies. | Component | Authority | Language | Visibility | Lifecycle | Release | |---|---|---|---|---|---| | [IICP](https://github.com/RobLe3/IICP) | normative protocol, registries and reviewed research | specification | public | active | 1.10.13 | -| iicp.network (source private) | cross-component issues, integration, conformance and project history | mixed | private | restructuring | — | -| iicp-network-ops (source private) | reviewed deployment, rollback, REACH and community operational source; no live credentials or production data | mixed | private | active | — | -| iicp-network-internal (source private) | FORGE, agent, project-management and reviewed private-history material; never a public build dependency | mixed | private | active | — | -| iicp-website (source private) | private iicp.network website source and static-build contracts; not planned for publication | typescript | private | active | 0.1.0 | | [iicp-directory-php](https://github.com/RobLe3/iicp-directory-php) | PHP reference directory implementation and current Genesis Seed code line | php | public | active | 1.10.91 | | [iicp-directory-rust](https://github.com/RobLe3/iicp-directory-rust) | pre-1.0 Rust directory operator preview; not the production Genesis authority | rust | public | operator-preview | 0.1.12 | | [iicp-client-python](https://github.com/RobLe3/iicp-client-python) | Python consumer and provider SDK | python | public | active | 0.7.104 | diff --git a/README.md b/README.md index 6cfa76f..5efc751 100644 --- a/README.md +++ b/README.md @@ -357,6 +357,15 @@ than inferred from source metadata. All normative language follows RFC 2119 / BCP 14. +For an independent protocol or standards review, start with +[`standards/REVIEWING.md`](standards/REVIEWING.md). The public +[`ecosystem/public-repositories.json`](ecosystem/public-repositories.json) +identifies the repositories and roles needed to continue implementation work. +The specification release and review-bundle procedures are reproducible from +public inputs and do not depend on the project's private development methods. +[`CONTINUATION.md`](CONTINUATION.md) explains how an independent implementation +or successor effort can preserve compatibility and release history. + --- ## Tools @@ -365,3 +374,8 @@ All normative language follows RFC 2119 / BCP 14. |------|---------| | [tools/protocol_integrity_analysis.py](tools/protocol_integrity_analysis.py) | Analyses a spec file for internal consistency | | [tools/quick_validation.py](tools/quick_validation.py) | Quick syntax + field validation against v1.4.2 | + +The simulation-oriented tools use optional scientific dependencies. Install +them in an isolated environment with +`python3 -m pip install -r tools/research-requirements.txt`. They are historical +research aids, not normative conformance or release gates. diff --git a/SECURITY.md b/SECURITY.md index c8dd95d..995d400 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,8 +1,39 @@ # Security policy -Do not disclose vulnerabilities through public issues. Use GitHub private -vulnerability reporting when available or contact community@iicp.network. +## Reporting a vulnerability + +Do not disclose an unpatched vulnerability through a public issue. Use +[GitHub private vulnerability reporting](https://github.com/RobLe3/IICP/security/advisories/new) +or contact `community@iicp.network`. Include the affected protocol or component +version, minimal synthetic reproduction, expected security boundary and +observed impact. Do not submit credentials, task payloads, production database contents, operator records, private endpoints or personal data. Protocol reports should use minimal synthetic reproductions and identify the affected version/profile. + +## Scope and support + +Security corrections target the latest published protocol suite and maintained +implementation release lines. Older releases may not receive backports. The +machine-readable repository and lifecycle list is +[`ecosystem/public-repositories.json`](ecosystem/public-repositories.json). + +Protocol requirements, implementation behavior and deployment state have +separate version axes. A specification fix does not prove that every deployed +node has adopted it, and an implementation fix does not silently redefine the +normative protocol. + +## Shared boundaries + +The public [`privacy adversary and trust model`](docs/security/privacy-adversary-and-trust-model.md) +states the common directory, relay, provider, identity and metadata boundaries. +In particular, transport security does not hide plaintext from the selected +execution provider, and a directory response alone is not provider +authentication. Unsupported required security or confidentiality profiles must +fail closed. + +After a correction can be disclosed safely, publish a sanitized issue, +advisory, test or release note sufficient for independent implementers to +understand the affected boundary and verify the fix. Do not publish private +incident records, credentials or personal development-method material. diff --git a/SPEC_RELEASE_PROCESS.md b/SPEC_RELEASE_PROCESS.md index 5356976..dc2bae5 100644 --- a/SPEC_RELEASE_PROCESS.md +++ b/SPEC_RELEASE_PROCESS.md @@ -24,6 +24,9 @@ implementation worktree. A draft profile or fixture update does not by itself ratify a suite release. 7. Build the release archive from a clean detached tag. Publish only immutable assets with SHA-256 checksums; never rebuild or replace an existing tag. +8. Run `tools/check_public_artifact_closure.py`. A release or standards-review + input that depends on a private repository, missing local file or + workstation path is not portable and MUST NOT be published. ## Promotion checklist @@ -37,6 +40,11 @@ implementation worktree. - Verify that status terms follow `SPEC_STATUS.md` and version axes follow `VERSIONING.md`. - Recheck every external registry claim immediately before publishing. +- Confirm that the archive contains its root license, governance, security, + contribution and continuation instructions. +- Run `python3 tools/check_public_artifact_closure.py --all-public` to catch + stale private dependencies elsewhere in the tracked public research and + documentation corpus before tagging. ## Boundaries @@ -48,3 +56,7 @@ implementation worktree. and cross-implementation evidence package. Semantic profiles are preferred. - Website and implementation-repository documentation are public references, not substitutes for this canonical source. +- Public technical research records the evidence and reasoning behind product + decisions. Private development methodology is neither normative evidence nor + a release dependency. The boundary is defined in + `docs/governance/public-artifact-boundary.md`. diff --git a/docs/external-evidence-participation.md b/docs/external-evidence-participation.md index b0d1e66..3541461 100644 --- a/docs/external-evidence-participation.md +++ b/docs/external-evidence-participation.md @@ -13,7 +13,7 @@ result independent. The machine-readable campaign index is [`external-participation-campaign-v1.json`](../evidence/external-participation-campaign-v1.json). It fixes the participant class, artifact versions, record, validation command -and submission path for the six current lanes. Every repository-owned state is +and submission path for the five public protocol and implementation lanes. Every repository-owned state is `awaiting-participant`; the project does not infer acceptance, consent, a result or a decision. Validate the index with: @@ -29,14 +29,13 @@ python3 tools/check_external_participation_campaign.py | Newcomer usability | IICP #94 | At least one non-technical reader, one developer, and one prospective node operator | The script below and the published website/operator guide | Three consented, anonymized session records and a findings summary | | Linux watchdog | Rust SDK #66 | A representative Linux/systemd operator, preferably including ARM | Rust SDK `0.7.104` and its opt-in native watchdog | Slow-start, pressure, reboot/logout, linger, restart, and rollback record | | Relay eligibility | IICP #59 | An independent relay operator and topology measurement environment | Current pre-normative relay research | Stale, forged, replayed, overloaded and partial-evidence cases without topology leakage | -| Qualified EU review | Root #768 and #801 | A qualified EU privacy and AI-law reviewer | The dated qualified-review packet | An attributable decision record and review memorandum | | Standards governance | IICP #47 | A consenting lead editor, backup editor, and change controller | The current draft candidate and governance decision contract | A non-sensitive governance decision with named stewardship roles | -The qualified reviewer starts with the dated packet linked from root #768 and -#801. The standards-governance lane starts from +Website and operator legal review is managed separately because its source +packet is not a protocol or implementation dependency. The standards-governance lane starts from [`submission-governance-decision-v1.json`](../standards/submission-governance-decision-v1.json) -and requires a consenting backup editor before IICP #47 can close. Neither lane -authorizes a deployment, publication or standards submission. +and requires a consenting backup editor before IICP #47 can close. That lane +does not authorize a deployment, publication or standards submission. Two related paths are documented below but are not campaign intake lanes. Public evidence access is a repeatable availability check for the evidence diff --git a/docs/governance/public-artifact-boundary.md b/docs/governance/public-artifact-boundary.md new file mode 100644 index 0000000..4b5dbb1 --- /dev/null +++ b/docs/governance/public-artifact-boundary.md @@ -0,0 +1,67 @@ +# Public artifact and private-method boundary + +## Purpose + +IICP's public repositories must be sufficient to review, implement, test and +maintain the protocol. They do not need to disclose the private development +system that produced the work. + +This boundary applies to specification releases, standards-review material, +public research, implementation repositories and conformance evidence. + +## Public artifacts + +The public record includes: + +- normative specifications, registries, schemas and compatibility rules; +- source code for public implementations; +- technical research that affected a feature or protocol decision; +- experimental methods, inputs and limitations needed to reproduce a result; +- alternatives considered, rejected approaches and compatibility consequences; +- public architecture and security decisions; +- milestone definitions expressed as observable acceptance criteria; +- conformance fixtures, tests and content-free evidence; +- release, build, maintenance and contribution instructions. + +A future implementer should be able to determine what was decided, which +evidence supported it, what remains uncertain and what would justify revisiting +the decision. + +## Private material + +Private material includes development-loop implementation, agent prompts, +orchestration, internal work selection, personal reasoning systems, private +meta-tools, credentials, private topology and operational history. Public +builds and protocol decisions must not depend on that material. + +Private tools may check public artifacts, but their names, scores or internal +state are not public acceptance evidence. The public evidence must be +reproducible with the commands and inputs shipped in the public repository. + +## Mixed-source treatment + +When private work produces a public product decision, publish a self-contained +record containing the question, evidence, alternatives, decision, +consequences, limitations and acceptance criteria. Do not publish the private +workflow that generated or prioritized the work. + +When a public artifact refers to private material, use one of these treatments: + +1. state the required technical rule in the public specification; +2. create a sanitized public decision or research record; +3. cite public fixture, test or release evidence; or +4. remove the reference when it is historical and unnecessary. + +Public issue summaries must not copy private comments, credentials, personal +data or operational details. + +## Closure rule + +A normative or review-facing artifact is self-contained only when every local +reference resolves within the public repository or release and every external +reference is publicly retrievable. A private repository, internal project path +or workstation-local path cannot be normative authority. + +The public-artifact closure checker enforces this mechanical boundary. Human +review remains responsible for deciding whether the published rationale and +evidence are sufficient. diff --git a/docs/security/privacy-adversary-and-trust-model.md b/docs/security/privacy-adversary-and-trust-model.md new file mode 100644 index 0000000..251fabc --- /dev/null +++ b/docs/security/privacy-adversary-and-trust-model.md @@ -0,0 +1,52 @@ +# Privacy adversary and trust model + +## Scope + +This document records the public threat boundaries used by IICP Core and +IICP-CX. It describes protocol properties, not a deployment certification. + +## Privacy adversaries + +| ID | Adversary | Observable or controllable surface | Required posture | +|---|---|---|---| +| PA-1 | Network observer | addresses, timing, volume and any transport not protected by an authenticated secure channel | Use authenticated transport security and avoid payload logging. | +| PA-2 | Relay operator | connection metadata and ciphertext carried through the relay | Keep task-encryption keys outside relay control; a relay must forward CX envelopes without decrypting them. | +| PA-3 | Directory operator | registration, discovery, intent and route metadata | Task payloads must not pass through or be stored by the directory. | +| PA-4 | Selected execution provider | plaintext request, response and inference state required for ordinary execution | Disclose this boundary. IICP-CX does not hide plaintext from the selected executor; local or separately attested confidential execution is required for a stronger property. | + +IICP transport confidentiality is not anonymity. Timing, volume, endpoint and +selection metadata can remain visible even when task content is encrypted. + +## Cooperative-inference threats + +Cooperative execution adds capability-boundary bypass, credit laundering, +timing inference, policy spoofing and receipt-identity substitution risks. The +public cooperative-inference specification defines the applicable controls: +provider policy enforcement, signed and replay-protected receipts, bounded +credit awards, caller binding and explicit local-only routing. A deployment +must not infer that one control removes the other threats. + +## Federation and identity-slot threats + +Federated directories and identity verifiers must account for: + +- tampered discovery results from a compromised replica; +- replayed, reordered or truncated signed event streams; +- stale or replaced replica keys; +- circular or conflicting trust assertions; +- unavailable identity documents; +- identity-scheme and signature-algorithm confusion; +- downgrade to unsigned or unverified results. + +Identity signatures bind the canonical message context. Verification dispatch +uses the asserted identity scheme, rejects mismatched key material and treats +network retrieval failure as unavailable evidence rather than successful +verification. Federation remains pre-normative until its separate evidence and +deployment gates pass. + +## Evidence boundary + +Specification requirements and conformance vectors show the intended behavior. +Implementation tests show that a particular release exercised that behavior. +Neither is a claim that a deployment, relay, operator or hardware environment +has been independently audited. diff --git a/ecosystem/current-versions.json b/ecosystem/current-versions.json index 4c6148d..03bcf07 100644 --- a/ecosystem/current-versions.json +++ b/ecosystem/current-versions.json @@ -41,12 +41,6 @@ "name": "iicp-web-node", "release": "0.2.4", "visibility": "public" - }, - "website": { - "lifecycle": "active", - "name": "iicp-website", - "release": "0.1.0", - "visibility": "private" } }, "generated_at": "2026-08-14", diff --git a/ecosystem/public-repositories.json b/ecosystem/public-repositories.json new file mode 100644 index 0000000..fae6e38 --- /dev/null +++ b/ecosystem/public-repositories.json @@ -0,0 +1,80 @@ +{ + "generated_at": "2026-08-14", + "repositories": [ + { + "authority": "normative protocol, registries and reviewed research", + "id": "specification", + "language": "specification", + "lifecycle": "active", + "name": "IICP", + "protocol": "1.9", + "release": "1.10.13", + "url": "https://github.com/RobLe3/IICP" + }, + { + "authority": "PHP reference directory implementation and current Genesis Seed code line", + "id": "directory-php", + "language": "php", + "lifecycle": "active", + "name": "iicp-directory-php", + "protocol": "1.9", + "release": "1.10.91", + "url": "https://github.com/RobLe3/iicp-directory-php" + }, + { + "authority": "pre-1.0 Rust directory operator preview; not the production Genesis authority", + "id": "directory-rust", + "language": "rust", + "lifecycle": "operator-preview", + "name": "iicp-directory-rust", + "protocol": "1.9", + "release": "0.1.12", + "url": "https://github.com/RobLe3/iicp-directory-rust" + }, + { + "authority": "Python consumer and provider SDK", + "id": "client-python", + "language": "python", + "lifecycle": "active", + "name": "iicp-client-python", + "package": "pypi:iicp-client", + "protocol": "1.9", + "release": "0.7.104", + "url": "https://github.com/RobLe3/iicp-client-python" + }, + { + "authority": "TypeScript consumer and provider SDK", + "id": "client-typescript", + "language": "typescript", + "lifecycle": "active", + "name": "iicp-client-typescript", + "package": "npm:@iicp/client", + "protocol": "1.9", + "release": "0.7.104", + "url": "https://github.com/RobLe3/iicp-client-typescript" + }, + { + "authority": "Rust consumer and provider SDK", + "id": "client-rust", + "language": "rust", + "lifecycle": "active", + "name": "iicp-client-rust", + "package": "crates:iicp-client", + "protocol": "1.9", + "release": "0.7.104", + "url": "https://github.com/RobLe3/iicp-client-rust" + }, + { + "authority": "browser-native IICP consumer and provider implementation", + "id": "web-node", + "language": "typescript", + "lifecycle": "experimental", + "name": "iicp-web-node", + "package": "npm:@iicp/web-node", + "protocol": "1.9", + "release": "0.2.4", + "url": "https://github.com/RobLe3/iicp-web-node" + } + ], + "schema": "iicp.public-repositories.v1" +} diff --git a/ecosystem/repositories.json b/ecosystem/repositories.json index 4de5351..36d8ac2 100644 --- a/ecosystem/repositories.json +++ b/ecosystem/repositories.json @@ -16,50 +16,6 @@ "protocol": "1.9", "release": "1.10.13" }, - { - "id": "project-hub", - "name": "iicp.network", - "url": "https://github.com/RobLe3/iicp.network", - "visibility": "private", - "lifecycle": "restructuring", - "authority": "cross-component issues, integration, conformance and project history", - "language": "mixed", - "protocol": "1.9", - "release": null - }, - { - "id": "private-operations", - "name": "iicp-network-ops", - "url": "https://github.com/RobLe3/iicp-network-ops", - "visibility": "private", - "lifecycle": "active", - "authority": "reviewed deployment, rollback, REACH and community operational source; no live credentials or production data", - "language": "mixed", - "protocol": "1.9", - "release": null - }, - { - "id": "private-project-history", - "name": "iicp-network-internal", - "url": "https://github.com/RobLe3/iicp-network-internal", - "visibility": "private", - "lifecycle": "active", - "authority": "FORGE, agent, project-management and reviewed private-history material; never a public build dependency", - "language": "mixed", - "protocol": "1.9", - "release": null - }, - { - "id": "website", - "name": "iicp-website", - "url": "https://github.com/RobLe3/iicp-website", - "visibility": "private", - "lifecycle": "active", - "authority": "private iicp.network website source and static-build contracts; not planned for publication", - "language": "typescript", - "protocol": "1.9", - "release": "0.1.0" - }, { "id": "directory-php", "name": "iicp-directory-php", diff --git a/evidence/external-participation-campaign-v1.json b/evidence/external-participation-campaign-v1.json index 390294e..96ec848 100644 --- a/evidence/external-participation-campaign-v1.json +++ b/evidence/external-participation-campaign-v1.json @@ -64,20 +64,6 @@ "submission": "publish the signed content-free bundle and link it on IICP #59", "state": "awaiting-participant" }, - { - "id": "qualified-eu-review", - "tracker": "https://github.com/RobLe3/iicp.network/issues/768", - "related_tracker": "https://github.com/RobLe3/iicp.network/issues/801", - "participant": "qualified EU privacy and AI-law reviewer", - "fixed_inputs": [ - "qualified review packet dated 2026-08-13", - "final Article 50 guidance dated 2026-07-20" - ], - "record": "https://github.com/RobLe3/iicp.network/blob/main/project/compliance/qualified-review-decision-v1.json", - "validator": "python3 scripts/check_qualified_review_packet.py ", - "submission": "return an attributable decision record and review memorandum for root #768 and #801", - "state": "awaiting-participant" - }, { "id": "standards-governance", "tracker": "https://github.com/RobLe3/IICP/issues/47", diff --git a/research/RESEARCH.md b/research/RESEARCH.md index c9180ea..160b514 100644 --- a/research/RESEARCH.md +++ b/research/RESEARCH.md @@ -1,12 +1,12 @@ # IICP Research Outcomes — Consolidated Reference -**Maintained by**: RESA loop (`project/resa-loop-prompt.md`), SPEC loop, and FORGE-5 ADOPTION sub-loop -**State file**: `project/RESA_STATE.json` (RESA tracks); WORK_QUEUE.json (ADOPTION-driven tracks) +**Authority**: public product research and decision evidence; normative status +is assigned only by the specification and release process **Last updated**: 2026-08-12 (heterogeneous routing and execution-privacy boundary research added) -> **Simulation-vs-live status (updated iter93)**: REP findings (F1–F16) and R1–R7 design findings derive from discrete-event simulation (Python harness, bounded network sizes 100–10,000). RS6 Phase 2 (iter93) added actual Ollama inference validation (phi3:mini vs qwen2.5:0.5b, 90 calls) — the quality-feedback loop is now partially cross-validated against real inference. Treat REP equilibrium findings as directional until REP6 full pilot completes. R4/R5/R6 routing findings are validated at simulation scale; real-pool behaviour to be confirmed by RS6 Phase 3. +> **Simulation-vs-live status (2026-05-18)**: REP findings (F1–F16) and R1–R7 design findings derive from discrete-event simulation (Python harness, bounded network sizes 100–10,000). RS6 Phase 2 added actual Ollama inference validation (phi3:mini vs qwen2.5:0.5b, 90 calls), so the quality-feedback result is partially cross-validated against real inference. Treat REP equilibrium findings as directional until the full pilot completes. R4/R5/R6 routing findings are validated at simulation scale; real-pool behaviour remains to be confirmed. -> **ADOPTION research status (added iter-301, 2026-05-21)**: GAMIFICATION + COMMUNITY-PLATFORM research tracks added to address ADOPTION binding constraint (W-016 / FC-001 — no confirmed external operators, D7 score corrected from 91 to ~60). These tracks are FORGE-5 ADOPTION sub-loop deliverables, distinct from RESA simulation tracks. Both research tracks have completed all design deliverables (5/5 each); implementation gated on #260 public-launch + ADR-030 operator identity layer. +> **Adoption research status (2026-05-21)**: the gamification and community-platform tracks document product options rather than protocol requirements. Both completed their design deliverables; implementation remains gated on a public-launch decision and the operator-identity prerequisite. > **Operational evidence checkpoint (2026-06-29)**: the reference implementation > now distinguishes live observation, controlled validation, simulation and @@ -57,24 +57,23 @@ spec writers, ADR authors, and implementation teams. | **REP** — Reputation & Tiered Access | #167-#172 | Design+Pilot complete | REP1-REP5 closed; REP6 (#172) simulation pending | | **R1R7** — Provider Selection & Multi-Path | #173-#179 | All design+simulation done | R1–R7 all closed; RS6 Phase 2 pilot complete | | **MESH** — Consolidator / Role-Routing | #180-#184 | Design phase | MESH1-MESH4 design done; MESH5 pilot pending | -| **GAMIFICATION** — Operator Recognition (Nerd Legacy) | #267, #269 (ADR-030) | **Research COMPLETE 5/5** (iter-294..300) | Awaiting PS review + #260 public-launch gate + ADR-030 Accepted before implementation | -| **COMMUNITY-PLATFORM** — Forum / BBS choice | #268 | **Research COMPLETE 5/5** (iter-301) | Lemmy recommended; awaiting maintainer sign-off | -| **INBOUND-ADAPTERS** — LLM API compat layer | #273 | **Research COMPLETE 1/1** (iter-370) | Priority matrix done: Ollama-compat Phase A, Anthropic-compat Phase B; implementation issues to be filed | +| **GAMIFICATION** — Operator Recognition (Nerd Legacy) | #267, #269 (ADR-030) | **Research complete: 5/5 deliverables** | Awaiting public product decision and operator-identity prerequisite before implementation | +| **COMMUNITY-PLATFORM** — Forum / BBS choice | #268 | **Research complete: 5/5 deliverables** | Lemmy recommended; awaiting maintainer product decision | +| **INBOUND-ADAPTERS** — LLM API compatibility layer | #273 | **Research complete: 1/1 deliverable** | Priority matrix recommends Ollama compatibility before Anthropic compatibility; implementation remains separately tracked | | **OPER-EVIDENCE** — live implementation evidence discipline | Reference implementation | **Active** | Separate live, validated, simulated and future claims; see validation methodology §7 | -| **STRATEGIC-PROFILES** — layered intent/capability/policy/evidence research | `iicp.network#619`, `RobLe3/IICP#2` | **Research complete; ratification gated** | Preserve stable URNs; publish profiles and shared fixtures before normative changes. | +| **STRATEGIC-PROFILES** — layered intent/capability/policy/evidence research | [IICP #55](https://github.com/RobLe3/IICP/issues/55) | **Research complete; ratification gated** | Preserve stable URNs; publish profiles and shared fixtures before normative changes. | | **HETEROGENEOUS-QUALITY** — evaluator-owned learned backend selection | [#135](https://github.com/RobLe3/IICP/issues/135) | **Initial experiment complete; Rust seam gated** | Pinned MetaHarness reproduction supports a client-only experiment after eligibility; an IICP-specific heterogeneous benchmark remains required before shared profile work. | | **EXECUTION-PRIVACY** — attested confidential execution | [#136](https://github.com/RobLe3/IICP/issues/136) | **Synthetic boundary vectors pass; hardware proof gated** | Ten content-free negative/positive vectors now exercise verifier signature, freshness, nonce, key binding, measurement, debug, TCB, boundary and downgrade checks. AMD SEV-SNP is the selected first hardware target; private-key containment and a complete measured worker remain unproven. | -**RESA composite**: **92.36/90.0 CONVERGED** (iter93, 2026-05-18). R-GATE-1 OPEN. - -**ADOPTION-driven research**: Gamification + Community-Platform tracks complete; both gated on maintainer review + #260 public-launch decision. See sections below. +Internal development scores are not public research evidence. The tables below +record the reproducible inputs, confidence limits and product-facing decisions. --- ## REP Track -**Charter**: `research/reputation-and-tiers-charter.md` -**ADRs**: ADR-026 (reputation as earned signal), ADR-027 (premium as paid axis) +**Charter**: `research/reputation-and-tiers-charter.md` +**ADRs**: ADR-026 (reputation as earned signal), ADR-027 (premium as paid axis) **Harness**: `research/simulation/rep/harness.py` ### Issue Map @@ -84,7 +83,7 @@ spec writers, ADR authors, and implementation teams. | REP1 #167 | Reputation mechanics and starting credit | Simulation | **OPEN** (ratification pending) | F1–F9, F16 — `REP1-starting-credit-recommendation-2026-05-18.md` | | REP2 #168 | Tier structure and transition rules | Simulation | **OPEN** (ratification pending) | F1–F12 — `REP2-tier-boundaries-recommendation-2026-05-18.md` | | REP3 #169 | Premium services taxonomy | Design-only | Closed | `REP3-premium-services-taxonomy.md` | -| REP4 #170 | Two-sided feedback collection | Design+schema | **CLOSED** iter93 | `REP4-feedback-mechanism-2026-05-18.md`, `research/rep-track/feedback-mechanism.md`, `spec/schemas/feedback-envelope.json` | +| REP4 #170 | Two-sided feedback collection | Design+schema | **CLOSED** | `REP4-feedback-mechanism-2026-05-18.md`, `research/rep-track/feedback-mechanism.md`, `spec/schemas/feedback-envelope.json` | | REP5 #171 | Whitewash and adversarial scenarios | Simulation | **CLOSED** | `REP5-adversarial-modeling-2026-05-18.md` | | REP6 #172 | Simulation harness + local pilot gate | Simulation+local | **OPEN** (simulation pending) | RS6-F1 (Phase 1 shadow), RS6-F2..F5 (Phase 2 Ollama pilot) | @@ -166,7 +165,7 @@ Confidence levels: **HIGH** = simulation-validated with sound methodology; **MED | Gap | Spec change needed | File | Status | |-----|-------------------|------|--------| -| Telemetry trust model | §T4 PROXY_TOKEN_AUTH + SYBIL_QUORUM + OUTLIER_WEIGHT | spec/iicp-telemetry.md | **DONE** (iter72) | +| Telemetry trust model | §T4 PROXY_TOKEN_AUTH + SYBIL_QUORUM + OUTLIER_WEIGHT | spec/iicp-telemetry.md | **DONE** | | T4.3 Outlier detection | Implement §T4.3 OUTLIER_WEIGHT — F14 confirmed latency is capturable | spec/iicp-telemetry.md | **OPEN** (#187 — ratification pending) | | Bootstrap traffic floor | §5.1.2: 1 job/session, threshold=100, session=30min, pool-guard=3 | spec/iicp-cooperative-inference.md | **DRAFTED** v0.6.2-draft; PENDING ratification (#168) | | Tier structure | §5.1.1: silver=0.40, gold=0.65, platinum=0.85, identity-age=720h | spec/iicp-cooperative-inference.md | **DRAFTED** v0.6.1-draft; PENDING ratification (#168) | @@ -180,7 +179,7 @@ Confidence levels: **HIGH** = simulation-validated with sound methodology; **MED ## R1R7 Track -**Charter**: `project/cc-instructions/CC-provider-selection-R1-R7-2026-05-17.md` +**Public evidence**: `research/findings/r1r7/` and the simulation sources listed below **ADRs**: ADR-025 (provider selection research track) ### Issue Map @@ -192,7 +191,7 @@ Confidence levels: **HIGH** = simulation-validated with sound methodology; **MED | R3 #175 | Discovery: centralized vs. DHT | Design | **CLOSED** | `R3-discovery-layer-2026-05-18.md` — R3-F1 | | R4 #176 | Selection policy comparison: ε-greedy vs harmonic/UCB/etc | Simulation | **CLOSED** | `R4-selection-policy-comparison-2026-05-18.md` — R4-F1..Fn | | R5 #177 | Adversarial robustness of selection policies | Simulation | **CLOSED** | `R5-adversarial-robustness-2026-05-18.md` — R5-F1..Fn | -| R6 #178 | Multi-path N-of-M strategies | Simulation | **CLOSED** iter90 | `R6-multi-path-execution-2026-05-18.md` — R6-F1..F6 | +| R6 #178 | Multi-path N-of-M strategies | Simulation | **CLOSED** | `R6-multi-path-execution-2026-05-18.md` — R6-F1..F6 | | R7 #179 | SSSP reality check | Design | **CLOSED** | `research/sssp-relevance-reality-check.md` — R7-F1 | ### Key Findings @@ -211,7 +210,7 @@ Confidence levels: **HIGH** = simulation-validated with sound methodology; **MED ## MESH Track -**Charter**: `project/cc-instructions/CC-mesh-consolidator-role-routing-MESH1-MESH5-2026-05-17.md` +**Public evidence**: `research/mesh-track/` and `research/simulation/mesh/` **ADRs**: ADR-028 (consolidator pattern + role-routing) ### Issue Map @@ -274,17 +273,17 @@ REP1/REP2 (tier thresholds ratified) ← PENDING PS ratification #168 **Issues**: #267 (research), #269 (ADR-030 Operator Identity & Anti-Sybil — prerequisite) **Deliverables location**: `research/gamification-track/` **Status**: Research COMPLETE (5/5 deliverables) — awaiting PS review + 8 rollout gates -**Concept doc**: `project/gamification.md` (public-facing project-level doc) +**Concept and decision evidence**: the five public deliverables in `research/gamification-track/` -### Deliverables (all complete iter-294..300) +### Deliverables -| # | File | Purpose | iter | -|---|------|---------|------| -| 01 | `01-design-rationale.md` | Earn-by-existing principle, multi-axis identity, prior art survey (StackOverflow / GitHub / Foldit / BOINC / Strava), constraints | 294 | -| 02 | `02-metric-mapping.md` | Rank/badge → telemetry mapping. 16/23 fully computable today; 7 partial bounded extensions; composite rank_score formula proposed | 296 | -| 03 | `03-anti-gaming.md` | 7 attack categories (sock-puppet, metric-stuffing, time-boxing, tier-surfing, identity-laundering, geographic spoofing, collusion); per-rank/badge mitigations; **hybrid operator identity proposed (→ ADR-030 candidate)**; 6 hard normative rules | 297 | -| 04 | `04-rollout-gates.md` | 8 sequential gates (G1 Identity → G2 Public-launch → G3 REACH multi-region → G4 ≥10 external operators → G5 Telemetry → G6 Spec+conformance → G7 Privacy+moderation → G8 Founding Cohort migration); 4-phase staged rollout (R1 quiet → R2 internal → R3 public → R4 first season close) | 299 | -| 05 | `05-api-surface.md` | 7 endpoints (4 public reads cacheable + 3 operator-authenticated writes); 4 tables (2 from ADR-030 + 2 new); 8 conformance test IDs (RECOG-PROF-01..PRIV-01); ~10 commits implementation estimate | 300 | +| # | File | Purpose | +|---|------|---------| +| 01 | `01-design-rationale.md` | Earn-by-existing principle, multi-axis identity, prior-art survey and constraints | +| 02 | `02-metric-mapping.md` | Rank/badge-to-telemetry mapping, coverage gaps and proposed composite score | +| 03 | `03-anti-gaming.md` | Seven attack categories, mitigations, operator-identity dependency and six proposed hard rules | +| 04 | `04-rollout-gates.md` | Eight evidence gates and four staged rollout states | +| 05 | `05-api-surface.md` | Proposed endpoints, persistence, conformance identifiers and implementation estimate | ### Key research findings @@ -309,7 +308,7 @@ REP1/REP2 (tier thresholds ratified) ← PENDING PS ratification #168 **Status**: Research COMPLETE (5/5 deliverables) — awaiting maintainer sign-off **Recommendation**: **Lemmy** (Rust + Postgres + AGPL + ActivityPub native) -### Deliverables (all complete iter-301) +### Deliverables | # | File | Purpose | |---|------|---------| @@ -341,12 +340,10 @@ REP1/REP2 (tier thresholds ratified) ← PENDING PS ratification #168 --- -## Maintenance Protocol +## Maintenance contract -**This document is a mandatory output of multiple loops — RESA (simulation tracks) AND FORGE-5 ADOPTION (Gamification / Community-Platform / future ADOPTION research) — update every iteration that touches a research track.** - -After each iteration that affects research: -1. Update "Last updated" header (date + iter number + composite score where applicable) +When public research changes: +1. Update the date and evidence classification. 2. Update Track Index status row for the affected track 3. Update Issue Map row: change Status and Findings columns 4. Add new findings to the finding table (sequentially numbered within track) @@ -355,8 +352,8 @@ After each iteration that affects research: 7. Update spec gaps table when new gaps are identified or existing ones closed 8. Update Cross-Track Insights if a new finding changes architectural understanding 9. Update High-Confidence Constraints if a finding changes a constraint -10. **For ADOPTION-driven tracks** (Gamification, Community-Platform): add a deliverable row to the track's section when a new research doc lands - -**Never skip this step.** RESEARCH.md is the authoritative consolidated reference — staleness here makes it useless as a reference for ARCS, CORC, and implementation teams. +10. Add a deliverable row when a new public research document lands. -The SPEC loop bumps the spec version and deploys to iicp.network when spec files change. +This index is product-facing research history. It neither changes normative +status nor authorizes a release or deployment. Specification versions change +only through the public release process. diff --git a/research/community-platform/04-dogfood-angle.md b/research/community-platform/04-dogfood-angle.md index 486df17..7c00e0e 100644 --- a/research/community-platform/04-dogfood-angle.md +++ b/research/community-platform/04-dogfood-angle.md @@ -102,8 +102,8 @@ Even if we never build it, the dogfood-angle document serves three purposes: runs one season. File a research-track issue in 2027 to re-evaluate; until then, this is folklore, not a roadmap item. -The dogfood angle is captured in `project/gamification.md` ("a future operator narrative") and -in `project/ARCHITECTURE.md` future-section as appropriate. No active work item. +This document preserves the public product rationale. It does not create an +active protocol work item or depend on private development-process material. --- diff --git a/research/credit-economy/08-founding-bonus-and-premium-reseller.md b/research/credit-economy/08-founding-bonus-and-premium-reseller.md index 8d90fb2..00a48c2 100644 --- a/research/credit-economy/08-founding-bonus-and-premium-reseller.md +++ b/research/credit-economy/08-founding-bonus-and-premium-reseller.md @@ -2,7 +2,7 @@ **Date**: 2026-05-22 **Status**: Research / Pre-spec -**Feeds**: ADR-031, ADR-032, spec/iicp-dir.md §registration, project/FOUNDING_COHORT_MIGRATION.md +**Feeds**: the credit-economy decisions and directory registration semantics **Depends on**: 01-model-tier-roi-simulation.md (Scheme C weights), 04-premium-credit-design.md (P-Credit system), 06-monetary-policy-mint-system.md (Mint structure) --- @@ -163,7 +163,8 @@ public function earn(string $nodeId, int $outputTokens, string $tier, string $ta ``` **Link to FOUNDING_COHORT_MIGRATION.md**: migration of the 8 current seed nodes to -the founding cohort status is covered in `project/FOUNDING_COHORT_MIGRATION.md`. +founding-cohort migration requires a separately reviewed, public operator +policy before it can affect protocol-visible behavior. All 8 seed nodes should receive `founding_multiplier = 4.0` at migration time (they registered before public launch and are treated as Day 0 registrants). diff --git a/research/credit-economy/09-scalability-safety-implementation-plan.md b/research/credit-economy/09-scalability-safety-implementation-plan.md index 9169533..cd9686c 100644 --- a/research/credit-economy/09-scalability-safety-implementation-plan.md +++ b/research/credit-economy/09-scalability-safety-implementation-plan.md @@ -660,7 +660,7 @@ Single-operator Mint (launch) has no attack surface — it's the directory maint | 7 Mint governance | 4h | MintController.php, routes/api.php | Parameter ossification | | 8 Non-CIP routing | 3h | adapter task.py, directory router | Free-rider (pending #302) | | 9 REACH probes | 2h | reach/probes/directory_conformance.py | Undetected failures | -| 10 ADR-031 + spec | 3h | project/decisions/ADR-031.md, spec/iicp-dir.md | Spec drift | +| 10 credit decision + spec | 3h | public decision record and `spec/v1.9/iicp-dir.md` | Spec drift | | **Total** | **32h** | | | **Order**: 1A → 1B → 3 → 2 → 4A → 5 → 6 → 7 → 4B → 9 → 8 → 10 diff --git a/research/credit-rate-calibration/01-rate-calibration-findings.md b/research/credit-rate-calibration/01-rate-calibration-findings.md index 9b9ca48..a5dbc67 100644 --- a/research/credit-rate-calibration/01-rate-calibration-findings.md +++ b/research/credit-rate-calibration/01-rate-calibration-findings.md @@ -4,7 +4,7 @@ **Date**: 2026-05-24 **Status**: Research / Pre-spec **Issue**: #305 -**Author**: ADOPTION sub-loop, FORGE iter-958 +**Status**: public research record **Depends on**: `research/credit-economy/02-routing-cost-design.md`, `research/credit-economy/05-spec-and-implementation-plan.md` **Feeds**: `spec/iicp-core.md §routing-costs`, `spec/iicp-dir.md §credit-economy`, proxy spend logic, `/api/v1/stats` diff --git a/research/cryptographic-trustworthiness/04-phase6-plus-roadmap.md b/research/cryptographic-trustworthiness/04-phase6-plus-roadmap.md index b38f5d9..6521a37 100644 --- a/research/cryptographic-trustworthiness/04-phase6-plus-roadmap.md +++ b/research/cryptographic-trustworthiness/04-phase6-plus-roadmap.md @@ -99,7 +99,7 @@ zkML addresses all three. A zkML proof asserts: "Model M with weight commitment | zkML proof generation for 7B in < 1 second | 2028+ | Custom ASICs for proving, or breakthrough algorithms | | IICP Phase 7 zkML track opens | When < 10 seconds achieved | Open implementation track per spec | -**Decision trigger**: When a publicly available, open-source zkML framework can prove a 7B parameter model inference in under 10 seconds on commodity cloud GPU hardware, open the IICP Phase 7 zkML implementation track. Until then, track as a research milestone in `FORGE_STATE.json`. +**Decision trigger**: When a publicly available, open-source zkML framework can prove a 7B parameter model inference in under 10 seconds on commodity cloud GPU hardware, open a public IICP Phase 7 zkML implementation proposal. Until then, retain this as a research milestone rather than an implementation claim. --- @@ -277,9 +277,9 @@ Challenge prompts must be: | Phase 6 (+ TEE + challenge-response) | Above + code/hardware integrity for TEE nodes; probabilistic quality floor; model identity signal via probe performance | | Phase 7+ (+ zkML) | Above + cryptographic proof of full computation; model weight identity; no trust-in-coordinator needed for hash verification | -### Research Trigger Conditions (Recommendations for FORGE State) +### Public research trigger conditions -Add to `project/FORGE_STATE.json` under a new `research_triggers` section: +Reassess this research when one of these evidence thresholds is met: 1. **zkML trigger**: When any open-source framework proves 7B parameter LLM inference in under 10 seconds on an H100 GPU, open Phase 7 zkML implementation issue and ADR. 2. **TEE trigger**: When at least 3 node operators have expressed interest in running TEE-attested nodes (GitHub issue survey), draft Phase 6 TEE spec additions. diff --git a/research/field-injection-resistance/01-null-field-injection-audit.md b/research/field-injection-resistance/01-null-field-injection-audit.md index b788486..e7d7f8b 100644 --- a/research/field-injection-resistance/01-null-field-injection-audit.md +++ b/research/field-injection-resistance/01-null-field-injection-audit.md @@ -4,7 +4,7 @@ **Date**: 2026-05-24 **Status**: Research / Pre-spec **Issue**: #303 -**Author**: CORC sub-loop, FORGE iter-957 +**Status**: public security research record **Feeds**: spec/iicp-dir.md §field-integrity, ADR-030 §Tier-2 attestation, NodeScorer.php, RegisterController.php --- @@ -203,7 +203,7 @@ the operator intended this registration with this payload. This is sufficient. |-----------|--------|---------| | `spec/iicp-dir.md` | Add `§Field Integrity and Injection Resistance` | New §5.x | | `spec/iicp-dir.md` | Remove or sentinel `latency_estimate_ms` field | §3.3 discover response | -| `project/decisions/ADR-030.md` | Add `jurisdiction_cc` to DID:web operator document | §Tier 2 DID:web | +| Public identity-profile decision | Add `jurisdiction_cc` to the reviewed operator-identity contract, if accepted | §Tier 2 DID:web | These are informational — spec authors should pull from this document. @@ -215,7 +215,7 @@ These are informational — spec authors should pull from this document. - `directory/app/Services/NodeScorer.php` — score computation (region diversity) - `directory/app/Services/ReputationService.php` — DELTA constants (-0.05, -0.05) - `directory/app/Http/Controllers/AuditReportController.php` — audit pattern reference -- `project/security/THREAT_MODEL.md` — TC-1 through TC-8 threat scope +- [`docs/security/privacy-adversary-and-trust-model.md`](../../docs/security/privacy-adversary-and-trust-model.md) — public adversary and trust boundary - `research/credit-economy/02-routing-cost-design.md` — tier_weight table (for F4-M1 p95 thresholds) - ADR-030 §Tier 2 attestation - Issue #300 (latency_estimate_ms directory-measured) diff --git a/research/field-injection-resistance/field-audit-2026-05-24.md b/research/field-injection-resistance/field-audit-2026-05-24.md index 5197dcc..b9cffbb 100644 --- a/research/field-injection-resistance/field-audit-2026-05-24.md +++ b/research/field-injection-resistance/field-audit-2026-05-24.md @@ -1,5 +1,5 @@ # Field Injection Resistance Audit -**Issue**: #303 | **Date**: 2026-05-24 | **Author**: CORC iter-879 +**Status**: public security audit | **Date**: 2026-05-24 --- @@ -63,8 +63,8 @@ Both can be implemented before Phase 6 identity work (ADR-030) is finalized. ## Related -- Issue: [#303](https://github.com/RobLe3/iicp.network/issues/303) -- Issue: [#300](https://github.com/RobLe3/iicp.network/issues/300) — latency_estimate_ms +- [`node-capability-format.md`](../../spec/v1.9/node-capability-format.md) — current public capability and evidence boundary +- [IICP issue #90](https://github.com/RobLe3/IICP/issues/90) — privacy-preserving multi-signal Sybil research - ADR-013 — Ed25519 operator identity - ADR-030 — Operator identity & anti-sybil (ADR draft) - `directory/app/Services/TrustAuditorService.php` — existing auditor diff --git a/research/findings/FRAME8-adversarial-review-simulation-2026-05-24.md b/research/findings/FRAME8-adversarial-review-simulation-2026-05-24.md index b2941f3..a846035 100644 --- a/research/findings/FRAME8-adversarial-review-simulation-2026-05-24.md +++ b/research/findings/FRAME8-adversarial-review-simulation-2026-05-24.md @@ -11,7 +11,7 @@ **Issue**: #242 (FRAME8: Adversarial network expert review) **Date**: 2026-05-24 **Status**: Internal simulation complete — external expert review remains externally blocked -**Author**: RESA loop, FORGE iter963 +**Status**: public adversarial research record **Parent**: #231 (iicp-framing.md spec) --- diff --git a/research/findings/MESH5-live-readiness-gate-2026-05-24.md b/research/findings/MESH5-live-readiness-gate-2026-05-24.md index 8a1a79a..9f9aa50 100644 --- a/research/findings/MESH5-live-readiness-gate-2026-05-24.md +++ b/research/findings/MESH5-live-readiness-gate-2026-05-24.md @@ -4,7 +4,7 @@ **Issue**: #184 (MESH5: Local pilot and live-readiness gate for MESH track) **Date**: 2026-05-24 **Status**: Complete — live-readiness assessed: NOT READY for consolidator pattern (insufficient operators) -**Author**: RESA loop, FORGE iter963 +**Status**: public readiness research record **Prereqs**: MESH1 (#180) ✓, MESH2 (#181) ✓, MESH3 (#182) ✓, MESH4 (#183) ✓ **Live mesh**: 8 nodes, operational since 2026-05-16 diff --git a/research/findings/SEC-unified-sybil-defense-2026-05-30.md b/research/findings/SEC-unified-sybil-defense-2026-05-30.md index 3e30189..566c464 100644 --- a/research/findings/SEC-unified-sybil-defense-2026-05-30.md +++ b/research/findings/SEC-unified-sybil-defense-2026-05-30.md @@ -3,7 +3,7 @@ **Date**: 2026-05-30 **Track**: Security (red-team #363 follow-up) **Status**: Research — proposes ADR-030 amendment + phased MVF sequence -**Author**: FORGE iter-1556 deep-research pass (Opus) +**Status**: public security research record **Inputs**: red-team Block 1 (`reports/redteam/01-directory-control-plane.md`), adversarial bypass review (RT-01b/02b/03b/05b), concept review (F1–F10), ADR-030, `research/cryptographic-trustworthiness/`, `research/results/rep/identity_age/`, `research/findings/REP-adversarial-sensitivity-2026-05-18.md`, `research/gamification-track/03-anti-gaming.md` --- diff --git a/research/findings/r1r7/R1-protocol-policy-boundary-2026-05-18.md b/research/findings/r1r7/R1-protocol-policy-boundary-2026-05-18.md index 3e57a44..c9e5b26 100644 --- a/research/findings/r1r7/R1-protocol-policy-boundary-2026-05-18.md +++ b/research/findings/r1r7/R1-protocol-policy-boundary-2026-05-18.md @@ -1,10 +1,10 @@ # R1 — Protocol/Policy Boundary for Provider Selection -**Track**: R1R7 — Provider Selection & Multi-Path Routing -**Issue**: #173 (R1: Protocol/policy boundary for provider selection) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter82 -**Length**: ≈1800 words (within ≤2000 limit) +**Track**: R1R7 — Provider Selection & Multi-Path Routing +**Issue**: #173 (R1: Protocol/policy boundary for provider selection) +**Date**: 2026-05-18 +**Status**: public research record +**Length**: ≈1800 words (within ≤2000 limit) **ADR impact**: Expands ADR-025; identifies 5 follow-up gaps. --- diff --git a/research/findings/r1r7/R2-multi-path-protocol-requirements-2026-05-18.md b/research/findings/r1r7/R2-multi-path-protocol-requirements-2026-05-18.md index 6164da8..b1d9ca5 100644 --- a/research/findings/r1r7/R2-multi-path-protocol-requirements-2026-05-18.md +++ b/research/findings/r1r7/R2-multi-path-protocol-requirements-2026-05-18.md @@ -1,11 +1,11 @@ # R2 — Multi-Path Inference: Protocol Requirements and Threat Model -**Track**: R1R7 — Provider Selection & Multi-Path Routing -**Issue**: #174 (R2: Multi-path inference requirements and threat model) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter82 -**Depends on**: R1 (#173) — protocol/policy boundary complete -**Length**: ≈1950 words (within ≤2000 limit) +**Track**: R1R7 — Provider Selection & Multi-Path Routing +**Issue**: #174 (R2: Multi-path inference requirements and threat model) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: R1 (#173) — protocol/policy boundary complete +**Length**: ≈1950 words (within ≤2000 limit) **ADR impact**: Proposes ADR-029 (multi-path envelope extension); flags ADR-024 and ADR-019 updates needed. --- diff --git a/research/findings/r1r7/R3-discovery-layer-2026-05-18.md b/research/findings/r1r7/R3-discovery-layer-2026-05-18.md index 022e47e..0c531a5 100644 --- a/research/findings/r1r7/R3-discovery-layer-2026-05-18.md +++ b/research/findings/r1r7/R3-discovery-layer-2026-05-18.md @@ -1,11 +1,11 @@ # R3 — Discovery Layer: Centralized Directory vs. DHT -**Track**: R1R7 — Provider Selection & Multi-Path Routing -**Issue**: #175 (R3: Discovery layer — centralized directory vs. DHT) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter82 -**Depends on**: R1 (#173) — protocol/policy boundary complete -**Length**: ≈1900 words (within ≤2000 limit) +**Track**: R1R7 — Provider Selection & Multi-Path Routing +**Issue**: #175 (R3: Discovery layer — centralized directory vs. DHT) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: R1 (#173) — protocol/policy boundary complete +**Length**: ≈1900 words (within ≤2000 limit) **Recommendation**: **Stay centralized through Phase 5; begin federated substrate with ADR-013; DHT gated on concrete trigger (§5).** --- diff --git a/research/findings/r1r7/R4-selection-policy-comparison-2026-05-18.md b/research/findings/r1r7/R4-selection-policy-comparison-2026-05-18.md index a575a5d..3ad6c6e 100644 --- a/research/findings/r1r7/R4-selection-policy-comparison-2026-05-18.md +++ b/research/findings/r1r7/R4-selection-policy-comparison-2026-05-18.md @@ -1,15 +1,15 @@ # R4 — Selection Policy Comparison: Weighted Scoring, ε-Greedy, Harmonic/Fractal, UCB -**Track**: R1R7 — Provider Selection & Multi-Path Routing -**Issue**: #176 (R4: Selection policy comparison) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter85 -**Depends on**: R1 (#173) -**Harness**: `research/selection-policy-sim/selection_policy_sim.py` -**Results**: `research/results/r4/r4_summary.json` -**Seed**: 42, 43, 44 (3 independent runs per configuration) -**Network sizes**: 100, 1000, 10000 nodes -**Jobs per run**: 10,000 +**Track**: R1R7 — Provider Selection & Multi-Path Routing +**Issue**: #176 (R4: Selection policy comparison) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: R1 (#173) +**Harness**: `research/selection-policy-sim/selection_policy_sim.py` +**Results**: `research/results/r4/r4_summary.json` +**Seed**: 42, 43, 44 (3 independent runs per configuration) +**Network sizes**: 100, 1000, 10000 nodes +**Jobs per run**: 10,000 **Confidence**: MED — quality model uses static node scores; real deployment has score decay, latency variation, and provider joins/departures that are not modeled. diff --git a/research/findings/r1r7/R5-adversarial-robustness-2026-05-18.md b/research/findings/r1r7/R5-adversarial-robustness-2026-05-18.md index e1f6df6..21157c5 100644 --- a/research/findings/r1r7/R5-adversarial-robustness-2026-05-18.md +++ b/research/findings/r1r7/R5-adversarial-robustness-2026-05-18.md @@ -1,16 +1,16 @@ # R5 — Adversarial Robustness of Selection Policies -**Track**: R1R7 — Provider Selection & Multi-Path Routing -**Issue**: #177 (R5: Adversarial robustness) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter87 -**Depends on**: R4 (#176), R5 harness extends `selection_policy_sim.py` -**Harness**: `research/selection-policy-sim/adversarial_sim.py` -**Results**: `research/results/r5/r5_summary.json` -**Seed**: 42, 43, 44 (3 independent runs per configuration) -**Network sizes**: 100, 1000, 10000 nodes -**Jobs per run**: 10,000 -**Detection threshold**: 20 consecutive failures → node demoted +**Track**: R1R7 — Provider Selection & Multi-Path Routing +**Issue**: #177 (R5: Adversarial robustness) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: R4 (#176), R5 harness extends `selection_policy_sim.py` +**Harness**: `research/selection-policy-sim/adversarial_sim.py` +**Results**: `research/results/r5/r5_summary.json` +**Seed**: 42, 43, 44 (3 independent runs per configuration) +**Network sizes**: 100, 1000, 10000 nodes +**Jobs per run**: 10,000 +**Detection threshold**: 20 consecutive failures → node demoted **Confidence**: MED — detection model is simplified (threshold, not probabilistic reputation); real-world detection would use reputation scoring not binary consecutive-failure counts. diff --git a/research/findings/r1r7/R6-multi-path-execution-2026-05-18.md b/research/findings/r1r7/R6-multi-path-execution-2026-05-18.md index 922069c..bf69d50 100644 --- a/research/findings/r1r7/R6-multi-path-execution-2026-05-18.md +++ b/research/findings/r1r7/R6-multi-path-execution-2026-05-18.md @@ -1,15 +1,15 @@ # R6 — Multi-Path Execution: Trade-Off Curves and Strategy Recommendations -**Track**: R1R7 — Provider Selection & Multi-Path Routing -**Issue**: #178 (R6: Multi-path execution simulation) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter90 -**Depends on**: R2 (#174 — protocol requirements), R4 (#176 — selection policy baseline) -**Harness**: `research/multi-path-execution-sim.py` -**Results**: `research/results/r6/r6_multipath_results.json` -**Seeds**: 42, 43, 44 (3-run average per configuration) -**Network sizes**: 100, 1000, 10000 nodes | **Jobs**: 2000 per run -**Selection policy**: ε-greedy (ε=0.05, from R4 algorithm B recommendation) +**Track**: R1R7 — Provider Selection & Multi-Path Routing +**Issue**: #178 (R6: Multi-path execution simulation) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: R2 (#174 — protocol requirements), R4 (#176 — selection policy baseline) +**Harness**: `research/multi-path-execution-sim.py` +**Results**: `research/results/r6/r6_multipath_results.json` +**Seeds**: 42, 43, 44 (3-run average per configuration) +**Network sizes**: 100, 1000, 10000 nodes | **Jobs**: 2000 per run +**Selection policy**: ε-greedy (ε=0.05, from R4 algorithm B recommendation) **Confidence**: MED — quality model uses static node scores; no latency variance or churn. --- @@ -35,7 +35,7 @@ | verifiable | 2.5 | Medium (0.8×) | Medium-high (1.5) | | unverifiable | 2.0 | Medium (1.0×) | Very high (2.5) — client can't detect | -**Net value formula** (per job): +**Net value formula** (per job): `nv = (value × success_rate) − (cost_multiplier × cost_weight × 0.15) − (mal_accepted_rate × mal_penalty)` ### 1.3 Provider pool diff --git a/research/findings/r1r7/RESA006-bootstrap-floor-threshold-2026-05-18.md b/research/findings/r1r7/RESA006-bootstrap-floor-threshold-2026-05-18.md index 3e40063..e51c46e 100644 --- a/research/findings/r1r7/RESA006-bootstrap-floor-threshold-2026-05-18.md +++ b/research/findings/r1r7/RESA006-bootstrap-floor-threshold-2026-05-18.md @@ -1,11 +1,11 @@ # RESA-006 — Bootstrap Floor Threshold Validation -**Track**: REP + SPEC (feeds §5.1.2 ratification) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter92 -**Harness**: `research/resa006-transient-window-sim.py` -**Results**: `research/results/resa006/resa006_results.json` -**Seeds**: 42, 43, 44 | **Pool sizes**: 100, 1000, 10000 +**Track**: REP + SPEC (feeds §5.1.2 ratification) +**Date**: 2026-05-18 +**Status**: public research record +**Harness**: `research/resa006-transient-window-sim.py` +**Results**: `research/results/resa006/resa006_results.json` +**Seeds**: 42, 43, 44 | **Pool sizes**: 100, 1000, 10000 **Confidence**: MED — static quality model; real node success rates vary over time. --- diff --git a/research/findings/r1r7/RS6-local-pilot-phase2-2026-05-18.md b/research/findings/r1r7/RS6-local-pilot-phase2-2026-05-18.md index 11319c3..1b68457 100644 --- a/research/findings/r1r7/RS6-local-pilot-phase2-2026-05-18.md +++ b/research/findings/r1r7/RS6-local-pilot-phase2-2026-05-18.md @@ -1,11 +1,11 @@ # RS6 — Phase 2 Local Inference Pilot -**Track**: REP (Reputation & Tiered Access) × RS6 (Live Pilot Gate) -**Date**: 2026-05-18 -**Author**: RESA loop, iter93 -**Harness**: `research/rs6-local-pilot.py` -**Results**: `research/results/rs6/rs6_phase2_results.json` -**Seeds**: 42, 43, 44 | **Tasks**: 30 | **Nodes**: 2 +**Track**: REP (Reputation & Tiered Access) × RS6 (Live Pilot Gate) +**Date**: 2026-05-18 +**Status**: public live-pilot research record +**Harness**: `research/rs6-local-pilot.py` +**Results**: `research/results/rs6/rs6_phase2_results.json` +**Seeds**: 42, 43, 44 | **Tasks**: 30 | **Nodes**: 2 **Confidence**: HIGH — actual Ollama inference (phi3:mini, qwen2.5:0.5b); 90 total task executions. --- @@ -36,11 +36,11 @@ latency/availability effects. ### 2.2 Protocol parameters -- Starting credit: sc=0.50 (REP1 recommendation) -- Selection: ε-greedy, ε=0.05 (Algorithm B, production default) -- Task-outcome delta: +0.01 success, −0.05 failure (REP1) -- Quality modifier: (intent_match − 3) × 0.001 per task (REP4) -- Floor: R_FLOOR = 0.30 +- Starting credit: sc=0.50 (REP1 recommendation) +- Selection: ε-greedy, ε=0.05 (Algorithm B, production default) +- Task-outcome delta: +0.01 success, −0.05 failure (REP1) +- Quality modifier: (intent_match − 3) × 0.001 per task (REP4) +- Floor: R_FLOOR = 0.30 ### 2.3 Tasks diff --git a/research/findings/r1r7/RS6-shadow-pilot-real-data-2026-05-18.md b/research/findings/r1r7/RS6-shadow-pilot-real-data-2026-05-18.md index 1194bd3..0566436 100644 --- a/research/findings/r1r7/RS6-shadow-pilot-real-data-2026-05-18.md +++ b/research/findings/r1r7/RS6-shadow-pilot-real-data-2026-05-18.md @@ -1,11 +1,11 @@ # RS6 Shadow Pilot — Real-Data Validation of Selection Policy Simulations -**Status**: RS6 Phase 1 (desk-based shadow test) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter87 -**RESA dimension**: RS6 — Live Pilot Gate -**Data source**: Live `https://iicp.network/api/v1/registry/nodes` (2026-05-18T12:xx UTC) -**Method**: Real node reputation scores as quality proxy; 10,000 synthetic jobs; all 5 R4 algorithms +**Status**: RS6 Phase 1 (desk-based shadow test) +**Date**: 2026-05-18 +**Status**: public research record +**RESA dimension**: RS6 — Live Pilot Gate +**Data source**: Live `https://iicp.network/api/v1/registry/nodes` (2026-05-18T12:xx UTC) +**Method**: Real node reputation scores as quality proxy; 10,000 synthetic jobs; all 5 R4 algorithms --- diff --git a/research/findings/rep/REP-assortative-matching-2026-05-18.md b/research/findings/rep/REP-assortative-matching-2026-05-18.md index 4f6a11c..4a732c4 100644 --- a/research/findings/rep/REP-assortative-matching-2026-05-18.md +++ b/research/findings/rep/REP-assortative-matching-2026-05-18.md @@ -3,7 +3,7 @@ **Track**: REP (Reputation & Tiered Access) — RS2 open work **Issues**: #167 (REP1: reputation mechanics), #168 (REP2: tier structure) **Date**: 2026-05-18 -**Author**: RESA loop, iter 8 +**Status**: public research record **Simulation**: `research/simulation/rep/assortative_matching.py`, 500 steps, n=100 **Results**: `research/results/rep/assortative/assortative_summary_steps500.json` **Answers**: Does assortative matching create an ossified tier system excluding newcomers? diff --git a/research/findings/rep/REP1-starting-credit-recommendation-2026-05-18.md b/research/findings/rep/REP1-starting-credit-recommendation-2026-05-18.md index 8c9a23f..2441360 100644 --- a/research/findings/rep/REP1-starting-credit-recommendation-2026-05-18.md +++ b/research/findings/rep/REP1-starting-credit-recommendation-2026-05-18.md @@ -3,7 +3,7 @@ **Track**: REP (Reputation & Tiered Access) **Issue**: #167 (REP1: Reputation mechanics and starting credit) **Date**: 2026-05-18 -**Author**: RESA loop, iter 5 +**Status**: public research record **Evidence basis**: F4 (silver/gold boundary positioning), F6 (convergence invariance) **Simulation**: `research/simulation/rep/harness.py` preliminary runs (iter69) + adversarial sweep (iter73) diff --git a/research/findings/rep/REP2-tier-boundaries-recommendation-2026-05-18.md b/research/findings/rep/REP2-tier-boundaries-recommendation-2026-05-18.md index 7871109..4fb2820 100644 --- a/research/findings/rep/REP2-tier-boundaries-recommendation-2026-05-18.md +++ b/research/findings/rep/REP2-tier-boundaries-recommendation-2026-05-18.md @@ -3,7 +3,7 @@ **Track**: REP (Reputation & Tiered Access) **Issue**: #168 (REP2: Tier structure and transition rules) **Date**: 2026-05-18 -**Author**: RESA loop, iter 6 +**Status**: public research record **Evidence basis**: F1 (scale invariance), F2 (adversarial isolation), F5 (demotion asymmetry), F7 (adversarial equilibrium), F10/F12 (identity-age gate validation) --- @@ -105,7 +105,7 @@ Before #168 can be closed, the following parameters need explicit ratification: ADR-026 currently lists tier thresholds as "candidates". This REP2 recommendation upgrades them to **recommended defaults** based on simulation evidence. The next SPEC iteration should: 1. Update ADR-026 §Decision to replace "candidate" with "recommended" -2. Add note about 90-day gate variant (not yet tested — coordinated collusion model RESA iter7) +2. Add note about the 90-day gate variant (not yet tested; see `REP4-coordinated-collusion-2026-05-18.md`). 3. Update spec/iicp-cooperative-inference.md §5 with final tier values (after REP1/REP2 formal closure) --- @@ -113,6 +113,6 @@ to **recommended defaults** based on simulation evidence. The next SPEC iteratio ## Open items for REP2 closure - [ ] Formal Protocol Steward ratification of the above tier boundary table -- [ ] 90-day gate variant simulation (coordinated collusion — RESA iter7, RS2 gap) +- [ ] 90-day gate variant simulation (coordinated-collusion and RS2 evidence gap) - [ ] Spec update: `spec/iicp-cooperative-inference.md §5.1` — tier thresholds as normative values - [ ] ADR-026 updated from "candidate" → "recommended" for all threshold values listed above diff --git a/research/findings/rep/REP4-coordinated-collusion-2026-05-18.md b/research/findings/rep/REP4-coordinated-collusion-2026-05-18.md index 364d5b2..1edbaf6 100644 --- a/research/findings/rep/REP4-coordinated-collusion-2026-05-18.md +++ b/research/findings/rep/REP4-coordinated-collusion-2026-05-18.md @@ -3,7 +3,7 @@ **Track**: REP (Reputation & Tiered Access) + RS2 (Harness Quality) **Issues**: #170 (REP4: feedback), #171 (REP5: adversarial) + RS2 open work **Date**: 2026-05-18 -**Author**: RESA loop, iter 7 +**Status**: public research record **Simulation**: `research/simulation/rep/coordinated_collusion.py`, 1000 steps, n_honest=10 **Results**: `research/results/rep/collusion/collusion_summary_steps1000.json` **Answers Q7**: Does a coordinated feedback ring (3+ high-reputation proxies) significantly inflate reputation? @@ -123,6 +123,6 @@ feedback signal by a factor of ~24×. - [ ] Assortative-matching ossification run: do high-reputation nodes preferentially route to each other, forming reputation cliques that exclude newcomers? Requires - a graph-based routing simulation (RESA iter8). + the graph-based routing simulation in `REP-assortative-matching-2026-05-18.md`. - [ ] 90-day identity-age gate variant: does a longer gate (2160h) reduce the strategic whitewash attack to near-zero? (F11 showed 3 cycles remain at 720h/3000 steps) diff --git a/research/findings/rep/REP4-feedback-mechanism-2026-05-18.md b/research/findings/rep/REP4-feedback-mechanism-2026-05-18.md index 93ab16a..46baf95 100644 --- a/research/findings/rep/REP4-feedback-mechanism-2026-05-18.md +++ b/research/findings/rep/REP4-feedback-mechanism-2026-05-18.md @@ -3,7 +3,7 @@ **Track**: REP (Reputation & Tiered Access) **Issue**: #170 (REP4: Two-sided feedback collection) **Date**: 2026-05-18 -**Author**: RESA loop, iter 6 +**Status**: public research record **Phase**: Design (no simulation required — mechanism design) **Related ADRs**: ADR-012 (reputation weight W_REP), ADR-023 (reputation delta rules), ADR-026 (earned signal) @@ -158,7 +158,7 @@ own provider nodes. **Defenses** (weaker here): - This requires coordinated operators with high identity_age and high reputation - The investment required (maintaining high-reputation proxies for 720h+ each) is a significant economic barrier -- Coordinated collusion is modeled in RESA iter7 (RS2→100 work) +- Coordinated collusion is modeled in `REP4-coordinated-collusion-2026-05-18.md`. --- @@ -215,5 +215,5 @@ REP4 issue #170 should remain open until: |---|---------|---------|--------| | Q5 | Does α_fb = 0.05 prevent feedback from overwhelming telemetry signal? | REP4 | Not simulated | | Q6 | Does commit-reveal with 10-min blind period adequately prevent anchoring? | REP4 | Not simulated | -| Q7 | Does coordinated feedback ring (3+ high-rep proxies) significantly inflate provider reputation? | REP4+RS2 | Coordinated collusion model (RESA iter7) | +| Q7 | Does coordinated feedback ring (3+ high-rep proxies) significantly inflate provider reputation? | REP4+RS2 | Coordinated-collusion model | | Q4 | Does client feedback suppress Sybil rating farms? | REP4 | Partially answered — identity weighting + quorum gate are the primary defenses | diff --git a/research/findings/rep/REP5-adversarial-modeling-2026-05-18.md b/research/findings/rep/REP5-adversarial-modeling-2026-05-18.md index 35fb9ee..c116e71 100644 --- a/research/findings/rep/REP5-adversarial-modeling-2026-05-18.md +++ b/research/findings/rep/REP5-adversarial-modeling-2026-05-18.md @@ -3,7 +3,7 @@ **Track**: REP (Reputation & Tiered Access) **Issue**: #171 (REP5: Whitewash and adversarial scenarios — modeling) **Date**: 2026-05-18 -**Author**: RESA loop, iter 5 +**Status**: public research record **Related findings**: F7 (adversarial equilibrium), F8 (zero whitewash resets), F9 (adversarial fraction resilience) **Simulation**: `research/simulation/rep/identity_age_gate.py`, 3000 steps, size=200 diff --git a/research/gamification-track/01-design-rationale.md b/research/gamification-track/01-design-rationale.md index 5a35885..031923b 100644 --- a/research/gamification-track/01-design-rationale.md +++ b/research/gamification-track/01-design-rationale.md @@ -2,7 +2,7 @@ **Status**: Draft (iter-294, 2026-05-21) **Tracking**: #267 (research) | gated on #260 (public-launch) for implementation -**Author**: FORGE-5 iter-294 ADOPTION work, maintainer concept +**Status**: public design-rationale record --- diff --git a/research/gamification-track/02-metric-mapping.md b/research/gamification-track/02-metric-mapping.md index 127b664..a755161 100644 --- a/research/gamification-track/02-metric-mapping.md +++ b/research/gamification-track/02-metric-mapping.md @@ -1,7 +1,7 @@ # Gamification Track 02 — Metric Mapping **Status**: Draft (iter-296, 2026-05-21) -**Companion**: `01-design-rationale.md`, `project/gamification.md` +**Companion**: `01-design-rationale.md` **Tracking**: #267 --- diff --git a/research/gamification-track/04-rollout-gates.md b/research/gamification-track/04-rollout-gates.md index 71f30f6..ccb6460 100644 --- a/research/gamification-track/04-rollout-gates.md +++ b/research/gamification-track/04-rollout-gates.md @@ -1,14 +1,14 @@ # Gamification Track 04 — Rollout Gates -**Status**: Draft (iter-299, 2026-05-21) +**Status**: Draft research record (2026-05-21) **Companion**: `01-design-rationale.md`, `02-metric-mapping.md`, `03-anti-gaming.md` -**Tracking**: #267 +**Tracking**: no active protocol implementation issue --- ## Purpose -Define the explicit conditions under which the gamification framework (#267) is **safe to +Define the explicit conditions under which the recognition framework is **safe to ship**. Gates are sequenced: a gate cannot open until all prior gates open. The maintainer is the sole authority on each gate decision; this document specifies the *evidence* required for disposition, not the disposition itself. @@ -20,11 +20,11 @@ can disposition without re-investigating prior gates. ### Gate G1 — Identity layer in place -**Required artifact**: ADR-030 (Operator Identity & Anti-Sybil) at status Accepted, with -implementation shipped to production directory. +**Required artifact**: a reviewed public operator-identity and anti-Sybil +decision, with its implementation released by the directory owner. **Evidence**: -- `project/decisions/ADR-030.md` status = Accepted +- the public decision has accepted status and testable acceptance criteria - `directory/database/migrations/...operators` migration applied to production - `POST /v1/operator` returning 201 in live API - ≥1 attested operator visible via `GET /v1/operator/{handle}/profile` @@ -33,16 +33,16 @@ implementation shipped to production directory. **Why**: Without operator identity, every sock-puppet attack from deliverable 03 succeeds. Shipping gamification before identity = leaderboards full of phantom operators. -### Gate G2 — Public-launch gate (#260) resolved +### Gate G2 — Public-launch decision resolved -**Required artifact**: `project/gates/CLOSED_BETA_TO_PUBLIC_GATE.md` either: +**Required artifact**: a public launch decision that either: - Documents the path to public launch with concrete completion criteria, AND those criteria are met, OR - Explicitly documents indefinite closed-beta posture with maintainer rationale (in which case gamification rollout is restricted to invited operators only, per Gate G4). **Evidence**: -- File exists, signed off by maintainer +- The decision exists in a public operator-facing artifact and is approved by the maintainer - If "public" path: all checklist items in gate doc are ✅ - If "indefinite closed-beta" path: rationale documented + Gate G4 adjusted @@ -72,7 +72,7 @@ IICP working group. **Evidence**: - `SELECT COUNT(DISTINCT operator_id) FROM operators WHERE attestation_status='attested' AND operator_id != 'genesis-cohort' ≥ 10` -- W-016 / FC-001 D7 score correction applied to FORGE5_STATE.json reflecting the new reality +- A public, content-free operator-count snapshot confirms the threshold **Why**: Gamifying a single-operator-group mesh is embarrassing. Leaderboards work as a recruiting tool only when there's a non-trivial population to compete in. The 10-operator @@ -120,8 +120,7 @@ Normative spec prevents drift between client implementations and the directory. ### Gate G7 — Privacy & moderation policy -**Required artifact**: `project/RECOGNITION_PRIVACY_POLICY.md` and -`project/RECOGNITION_MODERATION_POLICY.md`. +**Required artifact**: public recognition privacy and moderation policies. **Evidence**: - Privacy policy covers: data retained, what's public, how operators opt out of leaderboards, @@ -136,7 +135,7 @@ Moderation must be predictable so operators don't fear arbitrary deplatforming. ### Gate G8 — Founding Cohort migration plan -**Required artifact**: `project/FOUNDING_COHORT_MIGRATION.md`. +**Required artifact**: a public founding-cohort migration policy. **Evidence**: - Lists the existing 8 active nodes' `operator_id` assignments (Genesis Cohort) @@ -156,14 +155,14 @@ their badges. | Gate | Owner | Disposition trigger | Status check | |---|---|---|---| -| G1 Identity | PS + maintainer | ADR-030 Accepted + schema migrated | `ls project/decisions/ADR-030.md` + check status field | -| G2 Public-launch | Maintainer | #260 gate doc signed off | `project/gates/CLOSED_BETA_TO_PUBLIC_GATE.md` exists + maintainer signature | +| G1 Identity | protocol and directory owners | Identity decision accepted + schema migrated | public decision status plus released schema evidence | +| G2 Public-launch | Maintainer | Public launch decision approved | public decision plus maintainer approval | | G3 REACH multi-region | Maintainer + ops | ≥3 probe regions live for ≥90d | `/api/v1/stats` exposes ≥3 region keys | | G4 External operators | Auto-observed | ≥10 attested distinct operators | `gh issue view 269` comment with operator count snapshot | -| G5 Telemetry | CORC | All deliverable-02 partial items resolved | grep schema migrations | -| G6 Spec + conformance | ARCS | `spec/iicp-recognition.md` v ≥ 1.0 + REACH probes registered | `git log -- spec/iicp-recognition.md` shows v1.0 tag | -| G7 Policies | Maintainer | Both policy docs land | `ls project/RECOGNITION_*_POLICY.md` | -| G8 Founding Cohort | Maintainer | Migration plan committed | `ls project/FOUNDING_COHORT_MIGRATION.md` | +| G5 Telemetry | implementation owners | All deliverable-02 partial items resolved | released schema and migration evidence | +| G6 Spec + conformance | protocol owner | `spec/iicp-recognition.md` v ≥ 1.0 + probes registered | public release tag and conformance evidence | +| G7 Policies | Maintainer | Both policies published | stable public policy URLs | +| G8 Founding Cohort | Maintainer | Migration plan published | stable public policy URL | --- @@ -224,10 +223,9 @@ Prefer narrow halts (specific badge disabled, season paused) over full rollback. - `01-design-rationale.md` — principle (earn-by-existing, multi-axis identity) - `02-metric-mapping.md` — telemetry-readiness verification (16/23 fully computable, 7 partial) - `03-anti-gaming.md` — threat model + 6 hard normative rules + operator identity as central mitigation -- `project/decisions/ADR-030.md` — Operator Identity & Anti-Sybil Layer (G1 prerequisite) -- `project/gamification.md` — public-facing concept doc -- **Issues**: #267 (parent), #260 (G2), #269 (G1 = ADR-030) -- **WARDEN**: W-016 (G4 evidence — D7 score correction lands when external operator count is honest) +- [`iicp-identity-slot.md`](../../spec/v1.9/iicp-identity-slot.md) — public identity boundary +- [`iicp-recognition.md`](../../spec/v1.9/iicp-recognition.md) — public recognition semantics +- [`privacy-adversary-and-trust-model.md`](../../docs/security/privacy-adversary-and-trust-model.md) — public threat boundary --- diff --git a/research/inbound-adapters/01-adapter-priority-matrix.md b/research/inbound-adapters/01-adapter-priority-matrix.md index 7c336fc..11bb0fb 100644 --- a/research/inbound-adapters/01-adapter-priority-matrix.md +++ b/research/inbound-adapters/01-adapter-priority-matrix.md @@ -3,7 +3,7 @@ **Track**: #273 — Inbound LLM adapter parity **Status**: Research complete — implementation issues to be filed **Date**: 2026-05-21 -**FORGE iter**: 370 (ADOPTION) +**Status**: public adapter-priority research --- diff --git a/research/mesh-telemetry/01-tier-definitions.md b/research/mesh-telemetry/01-tier-definitions.md index bd6449a..d9a588c 100644 --- a/research/mesh-telemetry/01-tier-definitions.md +++ b/research/mesh-telemetry/01-tier-definitions.md @@ -2,7 +2,7 @@ **Issue**: #277 (ARCS+RESA mesh telemetry) **Date**: 2026-05-24 -**Author**: RESA loop, FORGE iter963 +**Status**: public telemetry research record **Status**: Complete --- diff --git a/research/mesh-track/MESH1-role-assignment-algorithm-2026-05-18.md b/research/mesh-track/MESH1-role-assignment-algorithm-2026-05-18.md index 809f3ca..0974e5f 100644 --- a/research/mesh-track/MESH1-role-assignment-algorithm-2026-05-18.md +++ b/research/mesh-track/MESH1-role-assignment-algorithm-2026-05-18.md @@ -1,11 +1,11 @@ # MESH1 — Role-Assignment Algorithm Design -**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection -**Issue**: #180 (MESH1: Role-assignment algorithm for general, specialist, and consolidator roles) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter82 -**Depends on**: REP1 (#167), REP2 (#168) — thresholds informative; design proceeds without ratified values -**Length**: ≈1900 words (within ≤2000 limit) +**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection +**Issue**: #180 (MESH1: Role-assignment algorithm for general, specialist, and consolidator roles) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: REP1 (#167), REP2 (#168) — thresholds informative; design proceeds without ratified values +**Length**: ≈1900 words (within ≤2000 limit) **ADR impact**: Expands ADR-028; specifies event-log format for ADR-013 compatibility. --- diff --git a/research/mesh-track/MESH2-consolidator-pool-dynamics-2026-05-18.md b/research/mesh-track/MESH2-consolidator-pool-dynamics-2026-05-18.md index 15fd01b..9f99824 100644 --- a/research/mesh-track/MESH2-consolidator-pool-dynamics-2026-05-18.md +++ b/research/mesh-track/MESH2-consolidator-pool-dynamics-2026-05-18.md @@ -1,12 +1,12 @@ # MESH2 — Consolidator Pool Dynamics and Capability Probes -**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection -**Issue**: #181 (MESH2: Consolidator pool dynamics and capability probes) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter83 +**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection +**Issue**: #181 (MESH2: Consolidator pool dynamics and capability probes) +**Date**: 2026-05-18 +**Status**: public research record **Depends on**: MESH1 (#180) — role-assignment algorithm; Algorithm A (conjunctive) and -operator-diversity HARD constraint are inputs to this document. -**Length**: ≈2000 words +operator-diversity HARD constraint are inputs to this document. +**Length**: ≈2000 words **ADR impact**: Expands ADR-028 §Open Questions (MESH2 item). Interaction with ADR-013 (signed event log for probe results) and ADR-026 (reputation as earned signal). diff --git a/research/mesh-track/MESH3-load-aware-selection-results-2026-05-18.md b/research/mesh-track/MESH3-load-aware-selection-results-2026-05-18.md index a509d62..bd952b6 100644 --- a/research/mesh-track/MESH3-load-aware-selection-results-2026-05-18.md +++ b/research/mesh-track/MESH3-load-aware-selection-results-2026-05-18.md @@ -1,13 +1,13 @@ # MESH3 — Load-Aware Selection: Preventing Oscillation in Role-Filtered Pools -**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection -**Issue**: #182 (MESH3: Load-aware selection — preventing oscillation) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter83 -**Depends on**: MESH1 (#180) -**Harness**: `research/simulation/mesh/load_selection.py` -**Results**: `research/results/mesh/load_selection_all.json` -**Seed**: 42 · Pool: 10 nodes · Steps: 500 · Tasks/step: 20 · Capacity: 4/node +**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection +**Issue**: #182 (MESH3: Load-aware selection — preventing oscillation) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: MESH1 (#180) +**Harness**: `research/simulation/mesh/load_selection.py` +**Results**: `research/results/mesh/load_selection_all.json` +**Seed**: 42 · Pool: 10 nodes · Steps: 500 · Tasks/step: 20 · Capacity: 4/node **Confidence**: MED — simulation validates relative ordering of formulas; absolute oscillation counts are harness-specific (task-drain-per-step model, not real-world duration). diff --git a/research/mesh-track/MESH4-consolidator-integration-results-2026-05-18.md b/research/mesh-track/MESH4-consolidator-integration-results-2026-05-18.md index 7d5164f..99e91d5 100644 --- a/research/mesh-track/MESH4-consolidator-integration-results-2026-05-18.md +++ b/research/mesh-track/MESH4-consolidator-integration-results-2026-05-18.md @@ -1,13 +1,13 @@ # MESH4 — Consolidator-Pattern Integration and Disagreement Resolution -**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection -**Issue**: #183 (MESH4: Consolidator-pattern integration and disagreement resolution) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter84 -**Depends on**: MESH1 (#180), MESH2 (#181) -**Harness**: `research/simulation/mesh/consolidator_integration.py` -**Results**: `research/results/mesh/consolidator_integration_all.json` -**Seed**: 42 · 300 trials per combination · 20 inference nodes · 10 consolidators +**Track**: MESH — Consolidator Pattern, Role-Based Routing, Load-Aware Selection +**Issue**: #183 (MESH4: Consolidator-pattern integration and disagreement resolution) +**Date**: 2026-05-18 +**Status**: public research record +**Depends on**: MESH1 (#180), MESH2 (#181) +**Harness**: `research/simulation/mesh/consolidator_integration.py` +**Results**: `research/results/mesh/consolidator_integration_all.json` +**Seed**: 42 · 300 trials per combination · 20 inference nodes · 10 consolidators **Confidence**: MED — quality model is a proxy; real synthesis quality depends on model capability and task type. Cost ratios are calibrated from realistic token estimates but not validated against live pricing data. diff --git a/research/nat-traversal/01-prior-art-survey.md b/research/nat-traversal/01-prior-art-survey.md index 4f65501..6ac18b5 100644 --- a/research/nat-traversal/01-prior-art-survey.md +++ b/research/nat-traversal/01-prior-art-survey.md @@ -1,7 +1,7 @@ # NAT Traversal — Prior-Art Survey -**Date**: 2026-05-26 (iter-1381) -**Issue**: [#328](https://github.com/RobLe3/iicp.network/issues/328) — NAT-aware client + node architecture +**Date**: 2026-05-26 +**Public tracking**: [IICP #42](https://github.com/RobLe3/IICP/issues/42) for transport/NAT claim boundaries and [IICP #59](https://github.com/RobLe3/IICP/issues/59) for relay eligibility **Maintainer directive**: 2026-05-26 *"we need to make the clients/nodes NAT aware and NAT enable with automatic adaption to the circumstance if NAT is detected"* --- @@ -302,5 +302,5 @@ adapter_start(): - Tailscale "How NAT traversal works": tailscale.com/blog/how-nat-traversal-works - Cloudflare Tunnel docs: developers.cloudflare.com/cloudflare-one/connections/connect-networks - BitTorrent BEP 32: stigmund.bitcheese.net/bep-0032.html (UPnP usage in BT) -- IICP issues: [#325](https://github.com/RobLe3/iicp.network/issues/325), [#326](https://github.com/RobLe3/iicp.network/issues/326), [#328](https://github.com/RobLe3/iicp.network/issues/328) +- Public protocol tracking: [IICP #42](https://github.com/RobLe3/IICP/issues/42) and [IICP #59](https://github.com/RobLe3/IICP/issues/59) - Maintainer directive 2026-05-26 diff --git a/research/nat-traversal/02-edge-cases-and-integration.md b/research/nat-traversal/02-edge-cases-and-integration.md index 9692ae9..8b720d0 100644 --- a/research/nat-traversal/02-edge-cases-and-integration.md +++ b/research/nat-traversal/02-edge-cases-and-integration.md @@ -3,7 +3,7 @@ **Date**: 2026-05-26 (iter-1394) **Trigger**: Live UPnP test against maintainer FRITZ!Box 6591 + VPN exposed a class of bugs the original PoC didn't anticipate. Maintainer directive: *"make sure you test more edge cases regarding the VPN, NAT and UPNP detection and it also would probably make sense to think about including this either in the dependencies or maybe add this as part fo the code within the different clients"*. -**Companion to**: `01-prior-art-survey.md` (the high-level design) + `project/decisions/ADR-041.md` (the architectural decision). +**Companion to**: `01-prior-art-survey.md` (the high-level design). This record contains the public rationale; it does not depend on a private decision file. --- @@ -189,9 +189,9 @@ For Phase 6+: ## References - `01-prior-art-survey.md` — survey of WebRTC/libp2p/Tailscale/CF Tunnel/UPnP -- `project/decisions/ADR-041.md` — the architectural decision this work derives from +- `01-prior-art-survey.md` — the public prior-art and architectural rationale - `adapter/src/adapter/network/nat_detector.py` — implementation (current state) -- Issue [#328](https://github.com/RobLe3/iicp.network/issues/328) — NAT-aware research arc -- Issue [#330](https://github.com/RobLe3/iicp.network/issues/330) — live FRITZ!Box test findings (CGNAT misdiagnosis corrected) +- [IICP #42](https://github.com/RobLe3/IICP/issues/42) — transport, port and NAT claim boundary +- [IICP #59](https://github.com/RobLe3/IICP/issues/59) — relay eligibility profile - `docs/nat-aware-adapter-setup.md` — operator-facing recipe - Live verification 2026-05-26 against FRITZ!Box 6591 Cable + WireGuard VPN diff --git a/research/portable-identity/01-wizard-ux.md b/research/portable-identity/01-wizard-ux.md index 2167027..1692931 100644 --- a/research/portable-identity/01-wizard-ux.md +++ b/research/portable-identity/01-wizard-ux.md @@ -2,7 +2,7 @@ **Issue**: #307 (Research: portable identity UX — onboarding wizard) **Date**: 2026-05-24 -**Author**: RESA loop, FORGE iter963 +**Status**: public identity UX research record --- diff --git a/research/rep-track/adversarial-modeling.md b/research/rep-track/adversarial-modeling.md index 4e1dfa3..2fee2d2 100644 --- a/research/rep-track/adversarial-modeling.md +++ b/research/rep-track/adversarial-modeling.md @@ -4,7 +4,7 @@ **Issue**: #171 (REP5: Whitewash and adversarial scenarios — modeling) **Date**: 2026-05-24 **Status**: Complete — all five attack vectors modeled; design holds -**Author**: RESA loop, FORGE iter963 +**Status**: public adversarial research record **Simulation evidence**: `research/simulation/rep/harness.py`, sweep F6–F12, F16 **Related findings**: `research/findings/REP-adversarial-sensitivity-2026-05-18.md` **Depends on**: REP1 (#167), REP2 (#168), REP4 (#170) diff --git a/research/rep-track/feedback-mechanism.md b/research/rep-track/feedback-mechanism.md index a772aa8..9458a55 100644 --- a/research/rep-track/feedback-mechanism.md +++ b/research/rep-track/feedback-mechanism.md @@ -4,7 +4,7 @@ **Issue**: #170 (REP4: Two-sided feedback collection) **Date**: 2026-05-18 **Status**: Design complete — schema stub at `spec/schemas/feedback-envelope.json` -**Author**: RESA loop, iter93 +**Status**: public research record **Depends on**: REP1 (`reputation-mechanics.md`), ADR-026 **Schema draft**: `spec/schemas/feedback-envelope.json` diff --git a/research/rep-track/live-readiness.md b/research/rep-track/live-readiness.md index 8b01bf8..a7a7d1c 100644 --- a/research/rep-track/live-readiness.md +++ b/research/rep-track/live-readiness.md @@ -4,7 +4,7 @@ **Issue**: #172 (REP6: Simulation harness, local pilot, and live-readiness gate) **Date**: 2026-05-24 **Status**: Complete — simulation harness validated, local pilot assessed, live-readiness gate: NOT READY -**Author**: RESA loop, FORGE iter963 +**Status**: public readiness research record **Prereqs**: REP1 (#167) ✓, REP2 (#168) ✓, REP3 (#169) ✓, REP4 (#170) ✓, REP5 (#171) ✓ **Harness**: `research/simulation/rep/harness.py`, `research/simulation/rep/sweep_adversarial.py` **Prior runs**: 72 adversarial sweep runs (F6–F12), F16 routing concentration diff --git a/research/rep-track/reputation-mechanics.md b/research/rep-track/reputation-mechanics.md index d3bed3b..e41df9e 100644 --- a/research/rep-track/reputation-mechanics.md +++ b/research/rep-track/reputation-mechanics.md @@ -4,7 +4,7 @@ **Issue**: #167 (REP1: Reputation mechanics and starting credit) **Date**: 2026-05-18 **Status**: Design complete — pending Protocol Steward ratification -**Author**: RESA loop, iter8 +**Status**: public research record **Simulation evidence**: `research/simulation/rep/harness.py`, F1–F9, F16 **Findings**: `research/findings/rep/REP1-starting-credit-recommendation-2026-05-18.md` diff --git a/research/rep-track/tier-structure.md b/research/rep-track/tier-structure.md index eb5625e..47bbdf3 100644 --- a/research/rep-track/tier-structure.md +++ b/research/rep-track/tier-structure.md @@ -4,7 +4,7 @@ **Issue**: #168 (REP2: Tier structure and transition rules) **Date**: 2026-05-18 **Status**: Design complete — pending Protocol Steward ratification -**Author**: RESA loop, iter8 +**Status**: public research record **Simulation evidence**: `research/simulation/rep/harness.py`, identity_age_gate.py, F1–F16 **Findings**: `research/findings/rep/REP2-tier-boundaries-recommendation-2026-05-18.md` diff --git a/research/reputation-and-tiers-charter.md b/research/reputation-and-tiers-charter.md index b721950..3d53ce4 100644 --- a/research/reputation-and-tiers-charter.md +++ b/research/reputation-and-tiers-charter.md @@ -66,4 +66,6 @@ Each REP issue identifies its testing phase: Charter created 2026-05-17. Issues REP1 through REP6 filed. ADR-026 (two-sided reputation) and ADR-027 (premium services axis) created as stubs. Execution order: maintainer triages. -**Context anchor**: STATE.md commit `a7fd2bf`, FORGE-5 C4_CONVERGED (composite 93.62, iter 57), Sentrux 7151, active_nodes=7, S.12 v0.6.0 normative (§5.1 reputation decay), ADR-013 Draft (federated control plane, hybrid trust), ADR-019 Accepted (declarative pricing). +**Context anchor**: the then-current S.12 reputation-decay semantics, +federated-control-plane research and declarative-pricing decision. Historical +internal quality scores and live node counts are not protocol evidence. diff --git a/research/runtime-supervision/cross-platform-node-supervision-liveness.md b/research/runtime-supervision/cross-platform-node-supervision-liveness.md index ee39334..84657af 100644 --- a/research/runtime-supervision/cross-platform-node-supervision-liveness.md +++ b/research/runtime-supervision/cross-platform-node-supervision-liveness.md @@ -161,5 +161,8 @@ injection, measured ARM/Pi timing, and a separate default-enable decision. | Rust SDK | [#65](https://github.com/RobLe3/iicp-client-rust/issues/65) | complete: effective service lifecycle | | Python SDK | [#68](https://github.com/RobLe3/iicp-client-python/issues/68) | complete: effective service lifecycle | | TypeScript SDK | [#62](https://github.com/RobLe3/iicp-client-typescript/issues/62) | complete: effective service lifecycle | -| Website | `iicp-website#24` (private) | complete in source; no deployment included | -| Operations | `iicp-network-ops#24` (private) | open: sanitized Pi incident classification | + +Website presentation and operator incident handling are separate deployment +concerns. They are not dependencies for the public runtime-health semantics or +SDK implementations listed above. The historical Pi incident remains +unclassified unless new evidence identifies its failure class. diff --git a/research/sssp-relevance-reality-check.md b/research/sssp-relevance-reality-check.md index 55bad12..cbca6e0 100644 --- a/research/sssp-relevance-reality-check.md +++ b/research/sssp-relevance-reality-check.md @@ -1,10 +1,10 @@ # R7 — SSSP Relevance Reality Check -**Track**: R1R7 — Provider Selection & Multi-Path Routing -**Issue**: #179 (R7: SSSP reality check — does shortest-path matter at any plausible scale?) -**Date**: 2026-05-18 -**Author**: RESA loop, FORGE iter 82 -**Length**: ≈1600 words (within ≤2000 limit) +**Track**: R1R7 — Provider Selection & Multi-Path Routing +**Issue**: #179 (R7: SSSP reality check — does shortest-path matter at any plausible scale?) +**Date**: 2026-05-18 +**Status**: public relevance assessment +**Length**: ≈1600 words (within ≤2000 limit) **Recommendation**: **Defer SSSP entirely** — trigger condition specified in §5. --- diff --git a/research/strategic/2026-07-11-layered-intent-capability-research.md b/research/strategic/2026-07-11-layered-intent-capability-research.md index 15ea70a..b74bc26 100644 --- a/research/strategic/2026-07-11-layered-intent-capability-research.md +++ b/research/strategic/2026-07-11-layered-intent-capability-research.md @@ -55,8 +55,8 @@ Before any profile becomes normative, the project requires: Tracking: [`RobLe3/IICP#2`](https://github.com/RobLe3/IICP/issues/2) for spec-source governance and -[`iicp.network#619`](https://github.com/RobLe3/iicp.network/issues/619) for -the strategic substrate. +[`RobLe3/IICP#55`](https://github.com/RobLe3/IICP/issues/55) for the intent, +capability and extension registry ratification gate. ## Interoperability boundary diff --git a/research/strategic/2026-08-12-execution-privacy-and-attested-confidential-execution.md b/research/strategic/2026-08-12-execution-privacy-and-attested-confidential-execution.md index c92bb32..cb8a144 100644 --- a/research/strategic/2026-08-12-execution-privacy-and-attested-confidential-execution.md +++ b/research/strategic/2026-08-12-execution-privacy-and-attested-confidential-execution.md @@ -57,7 +57,7 @@ The directory and relay do not need plaintext. The selected node does. - Rust `confidentiality.rs`, Python `_confidentiality.py` and TypeScript `confidentiality.ts` generate or load a node CX key from local persistent storage. - Rust `node.rs`, Python `node.py` and TypeScript `node.ts` decrypt in the ordinary node process before invoking the handler/backend. - All three SDKs advertise and enforce `response_encryption_v1`, but response encryption does not change the executor trust boundary. -- The existing compliance attestation is a signed project/conformance statement. It is not hardware remote attestation and must not be presented as such. +- The existing compliance attestation is a signed implementation-conformance statement. It is not hardware remote attestation and must not be presented as such. The June 2026 privacy reports reached the correct high-level conclusion: local execution is the strongest current option; TEE-attested execution is the realistic remote research direction; FHE is longer-term. This report updates and narrows that proposal against the current implementation and standards. It does not create a second privacy architecture. @@ -109,7 +109,7 @@ IICP should use the RATS role model rather than inventing a second attestation v | Verifier | local consumer verifier or an explicitly trusted verification service | | Attestation Results | normalized, time-bounded result consumed by client policy | | Relying Party | IICP consumer deciding whether to release the CX-encrypted task | -| Endorsements/reference values | vendor roots, firmware/runtime reference values and project/operator policy inputs | +| Endorsements/reference values | vendor roots, firmware/runtime reference values and reviewed operator policy inputs | RFC 9711 provides a standardized EAT claims framework and nonce-based freshness, but it is not a universal vendor-evidence decoder or protocol flow. Composite CPU/GPU attestation may use EAT submodules or platform-specific nested results. The selected research representation is an EAT Claims-Set encoded as a CWT, signed in tagged COSE_Sign1 and transported as `application/eat+cwt` with a provisional IICP profile identifier. Vendor evidence remains adapter-specific. diff --git a/research/transport/Phase3-completion-2026-05-24.md b/research/transport/Phase3-completion-2026-05-24.md index 35f721c..55c80d9 100644 --- a/research/transport/Phase3-completion-2026-05-24.md +++ b/research/transport/Phase3-completion-2026-05-24.md @@ -2,7 +2,7 @@ **Issue**: #230 (Transport: IICP network-layer standard) **Date**: 2026-05-24 -**Author**: RESA loop, FORGE iter963 +**Status**: public transport research record --- diff --git a/research/wasm/WASM-1-feasibility.md b/research/wasm/WASM-1-feasibility.md index ecf16fe..e9758ca 100644 --- a/research/wasm/WASM-1-feasibility.md +++ b/research/wasm/WASM-1-feasibility.md @@ -2,7 +2,7 @@ **Issue**: #292 (ADOPTION: WASM client adapter — browser-installable IICP mesh client) **Date**: 2026-05-24 -**Author**: RESA loop, FORGE iter963 +**Status**: public feasibility research record --- diff --git a/spec/v1.9/README.md b/spec/v1.9/README.md index 9634dca..031ac1d 100644 --- a/spec/v1.9/README.md +++ b/spec/v1.9/README.md @@ -80,8 +80,10 @@ Which ADR is authoritative for a given spec section: | `iicp-framing.md` | Binary framing, CBOR | ADR-002 (Phase 1+), ADR-024 | | `iicp-billing-extension.md` | Pricing declaration | ADR-019 | -For implementation ADRs and their current evidence, see the -[reference repository decision index](https://github.com/RobLe3/iicp.network/tree/main/project/decisions). +The public specifications and architecture records in `docs/architecture/` +state the current decisions. Historical implementation ADR identifiers in the +table above are provenance labels; they are not required to interpret the +normative text. --- diff --git a/spec/v1.9/conformance-test-suite.md b/spec/v1.9/conformance-test-suite.md index 6841632..86709be 100644 --- a/spec/v1.9/conformance-test-suite.md +++ b/spec/v1.9/conformance-test-suite.md @@ -376,7 +376,7 @@ runtime (transient network or node issue). | `SEC-TLS-01` | All directory connections over TLS 1.3 | Verified via `openssl s_client` in production | `reach/src/reach/probes/directory_conformance.py::probe_tls_version` | | `SEC-NONCE-01` | Duplicate Ed25519 gossip signature on peers endpoint → 409 | Replay detected and rejected within the peer replay window | `adapter/tests/test_nonce_replay.py::test_duplicate_nonce_rejected` | | `SEC-LEAK-01` | No stack trace in any error response | Automated scan: `grep -r "Traceback\|at line"` | `reach/src/reach/probes/directory_conformance.py::probe_no_stack_trace` | -| `SEC-LEAK-02` | No internal file paths in any response body | Automated scan: `grep -r "/home/\|/Users/"` | `reach/src/reach/probes/directory_conformance.py::probe_no_path_leak` | +| `SEC-LEAK-02` | No internal file paths in any response body | Automated scan for common Unix and Windows home-directory prefixes | `reach/src/reach/probes/directory_conformance.py::probe_no_path_leak` | | `SEC-RN-01` | Rust node rejects empty `auth.node_token` → 401 | Validates `validate_token` never enters open-mode | `iicp-node/tests/` (Rust integration tests) | | `SEC-RN-02` | Rust node rejects request with no `auth` field → 401 | Missing auth treated same as invalid token | `iicp-node/tests/` (Rust integration tests) | | `SEC-LOG-01` | Task payload content absent from adapter and proxy logs | Submit task with known content; grep adapter+proxy logs — payload must not appear | `adapter/tests/test_coverage_gates.py` | diff --git a/spec/v1.9/iicp-confidentiality.md b/spec/v1.9/iicp-confidentiality.md index e713adc..a5475a3 100644 --- a/spec/v1.9/iicp-confidentiality.md +++ b/spec/v1.9/iicp-confidentiality.md @@ -14,7 +14,7 @@ REGISTER/storage and `cx_public_key` is the sole discover/NODELIST CX field. The `IICP-E050` (collapsed decrypt/no-support) + `IICP-E049` (cx_public_key update auth) — see §6 implementation status. Full E060–E064 model is the Tier-2 target. (#360) **Tracking**: #360 (E2E payload confidentiality), #361 (privacy threat model) -**Foundation**: `project/SECURITY.md §Privacy Adversary Model` (PA-1..PA-4), +**Foundation**: `docs/security/privacy-adversary-and-trust-model.md` (PA-1..PA-4), `spec/iicp-core.md §8 Security` (SEC-PRIV-04/05/09) --- @@ -39,7 +39,7 @@ Tier 1 responses are **not** E2E encrypted; bidirectional response encryption is inference (TEE attestation) and metadata privacy are separate, tracked work (P2 / #361). This specification directly addresses Privacy Adversary classes PA-2 and PA-3 from -`project/SECURITY.md`: +the public privacy adversary and trust model: - **PA-2** (relay operator coercion): relay sees ciphertext only - **PA-3** (directory operator coercion): directory never sees task payloads (preserved from ADR-001/003) diff --git a/spec/v1.9/iicp-core.md b/spec/v1.9/iicp-core.md index e67efba..43955ea 100644 --- a/spec/v1.9/iicp-core.md +++ b/spec/v1.9/iicp-core.md @@ -411,7 +411,8 @@ the HTTPS endpoint configured by the operator and is not required to use 9484. **Phase 1 rationale (ADR-002)**: JSON over HTTPS was chosen for Phase 1 to maximise tooling compatibility and minimise implementation risk at PoC scale. CBOR and QUIC were -deferred explicitly to Phase 3 (see `project/decisions/ADR-002-phase1-transport.md`). +deferred; the current transport boundary and evidence are recorded in +`docs/architecture/environmental-independence-and-extension-architecture.md`. **Current transport evidence**: Maintained implementations support HTTP task endpoints and a native framed TCP profile. Deployment metadata can negotiate or @@ -458,8 +459,8 @@ All error responses MUST use structured JSON: { "error": { "code": "", "message": "" } } ``` -The full IICP-E numeric code registry (IICP-E001 through IICP-E032) is maintained in -`project/ARCHITECTURE.md §Error Codes`. Implementations MUST use those codes on the wire; +The IICP-E numeric code catalog is maintained in this section and its referenced +sub-protocol specifications. Implementations MUST use those codes on the wire; the slug codes above are the Phase 1 canonical names. Phase 2 / Phase 3 / Phase 5 codes in active use: @@ -504,7 +505,7 @@ in active use: - Relay nodes and directory operators MUST NOT log task payload content beyond the TTL required for rate-limiting. [→ SEC-PRIV-03] - Registration `node_id` MUST default to an anonymized UUID not tied to hardware or operator identity. [→ SEC-PRIV-08] - All IICP connections MUST use TLS 1.3 or higher with ephemeral key exchange (forward secrecy). [→ SEC-TLS-01, SEC-PRIV-09]. Same Phase 3+ port-9484 exception applies as above. -- **Privacy adversary model** (PA-1..PA-4) and IICP Privacy Tier taxonomy are normative in `project/SECURITY.md §Privacy Adversary Model` and SHALL be considered when implementing any component that handles task routing or node metadata. +- **Privacy adversary model** (PA-1..PA-4) and its trust boundaries are defined in `docs/security/privacy-adversary-and-trust-model.md` and SHALL be considered when implementing any component that handles task routing or node metadata. --- diff --git a/spec/v1.9/iicp-identity-slot.md b/spec/v1.9/iicp-identity-slot.md index 45504d7..b52383f 100644 --- a/spec/v1.9/iicp-identity-slot.md +++ b/spec/v1.9/iicp-identity-slot.md @@ -6,7 +6,8 @@ **Authority**: Protocol Steward **Linked ADRs**: ADR-034 (this slot; Proposed), ADR-019 (declarative pricing), ADR-020 (reputation stub), ADR-018 (federation), ADR-024 (signed message envelope; pending), ADR-030 (operator identity & anti-Sybil) **Tracking issues**: #150 (Identity Slot work package), #151 (this spec — D1) -**Bounded context**: BC-12 (Identity Context — see `project/ddd/BC-12-identity.md`) +**Bounded context**: identity assertions carried by protocol messages; issuance, +resolution policy and identity governance remain outside the slot. --- @@ -354,8 +355,8 @@ Reserved in the `IICP-IDSLOT-NN` namespace: ## 11. Threat Model Summary -See `project/security/THREAT_MODEL.md §TC-10` for federation-specific threats. -Slot-specific threats: +Federation-specific and slot-specific threats are summarized in +`docs/security/privacy-adversary-and-trust-model.md`. Slot-specific controls: - **Signature replay across messages**: mitigated by including message-specific fields (`task_id`, `seq`, `snapshot_seq`) in the canonical input. Replays diff --git a/spec/v1.9/iicp-recognition.md b/spec/v1.9/iicp-recognition.md index 5379a30..622b324 100644 --- a/spec/v1.9/iicp-recognition.md +++ b/spec/v1.9/iicp-recognition.md @@ -5,8 +5,8 @@ **Date**: 2026-06-05 (updated from 2026-05-26) **Changelog**: 0.6.0 — §5.4 reconciled to the **shipped** #310 lock-in detector (SPEC_UPDATE_PLAN Unit A, D5-A): keyed on `operator_pubkey` (not DID `identity_uri`); **genuine-served-node** gate (operator_verified + public_reachable + active + available) replaces the demand-scaled task-floor; **#1 reserved + 30-day-gate-exempt**; **GENESIS_MS = 2026-06-06** anchor named; FOUNDER_LOCKIN/SUCCESSION ride a **dedicated non-federated** signed chain (DIR-FED-16) with emission a tracked follow-up; §8 rule 8 + RECOG-FND-01/05/06 aligned; RECOG-FND IDs marked pending in conformance-suite. 0.5.0 — §5.4 Founder ordinals + §8 founder hard rules (8–12) + §10 RECOG-FND-01..06 (#309/#461, ratified tiers). 0.4.0 — §12 proposed defaults. **Tracking**: #309 (this spec graduation), #267 (research), #269 (ADR-030 — closed 2026-05-26, file exists at Proposed) -**Foundation**: ADR-034 (Identity Slot), S.15 (`spec/iicp-identity-slot.md`), BC-12 (`project/ddd/BC-12-identity.md`) — operator identity composes on top of the Identity Slot -**Companion**: `project/gamification.md` (project-level concept), `research/gamification-track/` (rationale, metric mapping, anti-gaming, rollout gates, API surface) +**Foundation**: ADR-034 (Identity Slot), S.15 (`spec/iicp-identity-slot.md`) — operator identity composes on top of the Identity Slot +**Companion**: `research/gamification-track/` (rationale, metric mapping, anti-gaming, rollout gates, API surface) --- @@ -437,7 +437,9 @@ Per `research/gamification-track/04-rollout-gates.md`, this spec MUST NOT have a RECOG-Provider implementation deployed to production until ALL of these gates clear: - **G1**: ADR-030 Accepted + operator identity implementation shipped -- **G2**: `project/gates/CLOSED_BETA_TO_PUBLIC_GATE.md` resolved (either path) +- **G2**: a public maintainer decision records either launch authorization or a + continued-beta posture after the external-operator, incident-response, + installation, abuse-mitigation and contributor-readiness evidence is reviewed - **G3**: REACH geographic expansion to ≥3 probe origins - **G4**: ≥10 attested external operators in production - **G5**: All "partial" telemetry items from gamification deliverable 02 resolved diff --git a/spec/v1.9/iicp-semantics.md b/spec/v1.9/iicp-semantics.md index 00d1fbb..0f042db 100644 --- a/spec/v1.9/iicp-semantics.md +++ b/spec/v1.9/iicp-semantics.md @@ -639,7 +639,8 @@ Conformance: REP-07 (conformance-test-suite.md §13.6). This section consolidates the normative anti-sybil mitigations scattered across §11, the recognition spec, and the security model. It provides a single threat model, a table of enumerated mitigations with conformance IDs, an attack verification analysis, and an honest -gap table covering what is **not** yet mitigated. Cross-reference: `project/SECURITY.md` §TC-9, +gap table covering what is **not** yet mitigated. Cross-reference: +`docs/security/privacy-adversary-and-trust-model.md` and `spec/iicp-recognition.md` §8. ### 12.1 Threat model @@ -671,7 +672,7 @@ but directory-grade conformance is NOT broken by their absence. | SYB-05 | T-SYB-03 | MUST | Quorum reporter independence: proxy reporters that do not satisfy age ≥ 3 days AND reputation ≥ 0.55 MUST be acknowledged but MUST NOT count toward quorum (RT-03b, §11.7). | REP-06 | | SYB-06 | T-SYB-04 | MUST | Per-reporter audit rate limit: ≤1 audit report per reporter per 24h per target, AND ≤2 distinct reporters per target per day counted toward score (RT-05, §11.5). | REP-03 | | SYB-07 | T-SYB-04 | MUST | Audit-report reporter eligibility: reporter MUST satisfy age ≥ 3 days AND reputation ≥ 0.55; ineligible reports acknowledged (HTTP 202) but MUST NOT reduce the target score (RT-05b, §11.8). | REP-07 | -| SYB-08 | T-SYB-05 | MUST | Credit laundering rate limit: ≤1,000 credits awarded per `node_id` per hour; excess MUST be rejected with HTTP 429 (TC-9b, `project/SECURITY.md §TC-9b`). | — | +| SYB-08 | T-SYB-05 | MUST | Credit laundering rate limit: ≤1,000 credits awarded per `node_id` per hour; excess MUST be rejected with HTTP 429 (TC-9b; see `iicp-cooperative-inference.md` §10.6). | — | | SYB-09 | T-SYB-06 | MUST | Identity permanence: operator `identity_uri` is pinned on first-use (ADR-034); re-registration with a different `identity_uri` creates a new zero-reputation operator; re-registration with the same `identity_uri` after a flag does NOT clear the flag (`spec/iicp-recognition.md §8` rule 5). | RECOG-AG-05 | | SYB-10 | T-SYB-07 | MUST | Badge task-count collusion barrier: task counts toward badge thresholds with a `≥1,000` task requirement MUST require ≥3 distinct proxy `node_id` contributors (`spec/iicp-recognition.md §8` rule 3). | RECOG-AG-03 | | SYB-11 | T-SYB-07 | MUST | Multi-node operator diversity isolation: same operator's multiple nodes MUST NOT multiply operator-diversity scores (Country Pioneer, Diversity Champion, Founding Cohort) (`spec/iicp-recognition.md §8` rule 1). | RECOG-AG-01 | diff --git a/spec/v1.9/iicp-telemetry.md b/spec/v1.9/iicp-telemetry.md index 777a4a4..9b4793f 100644 --- a/spec/v1.9/iicp-telemetry.md +++ b/spec/v1.9/iicp-telemetry.md @@ -79,7 +79,7 @@ implementation that accepts `node_token` Bearer on telemetry submissions is **non-conformant**. On auth failure, the directory MUST return HTTP 401 with error code `IICP-E032` -(see `project/ARCHITECTURE.md` Phase 5 proxy telemetry error codes). +(see `iicp-core.md` §7). The `proxy_node_id` field is REQUIRED in the request body. If absent, the directory MUST return HTTP 401 with `IICP-E032`. diff --git a/spec/v1.9/iicp-v1.5-draft.md b/spec/v1.9/iicp-v1.5-draft.md index 2b8b682..09606d1 100644 --- a/spec/v1.9/iicp-v1.5-draft.md +++ b/spec/v1.9/iicp-v1.5-draft.md @@ -110,8 +110,8 @@ IICP v1.5 │ ├── Semantics (SHOULD) │ └── spec/iicp-semantics.md -│ → Scoring formula: project/ARCHITECTURE.md §ADR-008 -│ → Retry policy: project/RELIABILITY.md §Retry +│ → Scoring and selection: spec/iicp-semantics.md §4 +│ → Retry policy: spec/iicp-semantics.md §5 │ ├── Sub-protocols │ ├── spec/iicp-dir.md (IICP-DIR — directory) diff --git a/spec/v1.9/iicp-v1.5-overview.md b/spec/v1.9/iicp-v1.5-overview.md index c27be36..41871b6 100644 --- a/spec/v1.9/iicp-v1.5-overview.md +++ b/spec/v1.9/iicp-v1.5-overview.md @@ -103,8 +103,8 @@ IICP v1.5 │ ├── Semantics (SHOULD) │ └── spec/iicp-semantics.md -│ → Scoring formula: project/ARCHITECTURE.md §ADR-008 -│ → Retry policy: project/RELIABILITY.md §Retry +│ → Scoring and selection: spec/iicp-semantics.md §4 +│ → Retry policy: spec/iicp-semantics.md §5 │ ├── Sub-protocols │ ├── spec/iicp-dir.md (IICP-DIR — directory) diff --git a/spec/v1.9/release-integrity-manifest.json b/spec/v1.9/release-integrity-manifest.json index 9ad8b36..fc45eea 100644 --- a/spec/v1.9/release-integrity-manifest.json +++ b/spec/v1.9/release-integrity-manifest.json @@ -2,9 +2,14 @@ "files": { ".github/workflows/profile-fixtures.yml": "5f15a799aeac39a51a7d1ec36f2ec6d61cfe077599a66df2b7334284dcdab6c8", "CHANGELOG.md": "d3919869b171eaa05876b39f4ba0ef80cd41ad36424119dbeaf96be88eab0f03", - "IMPLEMENTATIONS.md": "b97be4cab278cd6339a3e317671e9139c97c728a85af90bcaf16f662add2130f", - "README.md": "0bef256a60f3c254d08062c6ac21e39166e279ce5cf886eb5efffbaf0cf65957", - "SPEC_RELEASE_PROCESS.md": "8145897d8b3768bcfdab1121fcd081af98f2a52044fbe8835240b0059a07c1fd", + "CONTINUATION.md": "b35ada951db64371d4766026d609133639cdc48692c5f50ecb20c072d4c8d26c", + "CONTRIBUTING.md": "4b4f82a12e8422e1105591781dc69e222734315fcb6ff78b074a20c2e52df7cb", + "GOVERNANCE.md": "aaf2eaf1f31347ffdd8e9b9ec060618b3cbcac6f35fc773352cf0a3fd7475dcd", + "IMPLEMENTATIONS.md": "4cc3b441a2445373d76c569bbafd97f217d1254d332b003ae29bb96df0f9651d", + "LICENSE": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "README.md": "71e48264b3ee01c5e57b260ae128de15e1cafee2e04bfd0d004a4836f681e1ae", + "SECURITY.md": "80eee7c221d025a92cab8aca82777e3bd89bfc9b267ea0aa6c9fbafb639c3ef3", + "SPEC_RELEASE_PROCESS.md": "b028249056253cc1a6327b7c03910eedbe0267f97d44027f8560ccfc955bce8f", "SPEC_STATUS.md": "90935da47e9a249aceb01213011b8aa4f031613b6d14a532da693005992025b4", "VERSIONING.md": "dbe41987cacbcaeba8b1b5c688278c994177b6d66f9066743d33f03be284322b", "conformance-runner/CLEAN_ROOM_IMPLEMENTATION.md": "3c228cb5306e52c522fe091e2cd9cfa6e1a5d6b6e17288c8f19c30051f4b99b8", @@ -35,14 +40,17 @@ "docs/architecture/portability-and-non-capture.md": "98f56e514014514fccdd4a12f685722b158416ef3a1836384d2732aaad0a2823", "docs/architecture/task-time-semantics-v1.json": "645d21c171dc483252e1bd380b45066351ad86f2db67bf5ebd3a6e12d5bd73aa", "docs/architecture/task-time-semantics.md": "8662999ee16a7a777ac420a1909c0c9f89eb60b430ce3fca4eb0f3caf10d9f49", - "docs/external-evidence-participation.md": "43bf2134e08e0e89bda4f0b335a635812293b8a5048a4e3aca3995ea5155c48e", + "docs/external-evidence-participation.md": "b7e02c6c7dd1621f2cfc5457616bf9557c38daef23606022c53b72540773f7fd", + "docs/governance/public-artifact-boundary.md": "776b00e46e5e6645d32d10761fe24dcb488aff2a62f647df0eb58bf0fee9bea0", "docs/operator-onboarding-recovery.md": "1dbf10a2a46ef110e545871ccce0a5a8e63838c1f85acc53cbcb4c0dfb2c34b1", + "docs/security/privacy-adversary-and-trust-model.md": "3e6a44b880e5b429e5be978f358d9145bab66c8024e2f1e0106c51f92482ca38", "ecosystem/CURRENT_VERSIONS.md": "141bf767269284906a9589922c15a906766fdf5c5a564ee6cb916b3ddf8a31ea", - "ecosystem/current-versions.json": "495b7a175ef2b5609ff3ce286148d07dcaaa13326ba4f9fbe8036058760b82d7", + "ecosystem/current-versions.json": "b707aaf1a3dd0b091744350a7481b385c79c43bbdd21a25709a0343de4917ef2", + "ecosystem/public-repositories.json": "f9b909b4d97fbbf16fdbbe8a994c2dad800912b19d83ed05f1b170a41525fb9b", "ecosystem/releases.json": "405ee1c5e39856536e40bd31c55b6177d093a48c11d3bf7f89141f346deb7530", - "ecosystem/repositories.json": "abd90b829551a5ec339a4e62b2223be3078cabbb9bb8d05fc04bf2a9147436f8", + "ecosystem/repositories.json": "d3ce2b1b8548d5ad38430ac4042210e64bffb3f2a1b9423d62b77754bed95f17", "evidence/clean-room-interoperability-record-v1.json": "907a769090908ec1169c04f8e276396bb644765c0cb98bee735320467c449bc9", - "evidence/external-participation-campaign-v1.json": "1864063a9cccca268936f5ac4f3acd055533cd5f403c0c91fe1dbe146316d78c", + "evidence/external-participation-campaign-v1.json": "bab601f5d051ba63117369057687423a49b8a02dd086df6002395285c12ab2b3", "evidence/newcomer-validation-record-v1.json": "5fad1491f8c85a0517164b5aed0a13d7992747b2f211efd27bdec7e287ec5181", "evidence/public-evidence-access-v1.json": "fc06068de5bb842e182cf22626abfb9f23bdc299d058cfed255d4828f5b37e8b", "evidence/relay-eligibility-record-v1.json": "33205747a262671d7fc18eb032f542046e0eba549ee01a1040b935d33d48cec0", @@ -102,34 +110,34 @@ "schemas/nodelist.json": "f8720a77210679ca08d843ae4967de11dc5b6666100910173dc3ec0f6a44a405", "schemas/task.json": "adf60dd8670658904cd853239633cd1f36e9d1acbfa526dd62d31c4cbe31e61e", "spec/v1.9/IICP-core-phase1-profile.md": "59b8096b20358b5c5272c92726779d04896d49ed8ef7668b1dc0fd321fc947c3", - "spec/v1.9/README.md": "4b611afe24fee1dffa93c28210c68d97cd5a3d6bc58fa6b98ca7530928d6330a", + "spec/v1.9/README.md": "84bfeb008835c060713a7dfc84a0fafa383f4e9d3be07142b994c3a619ac1d3e", "spec/v1.9/VERSION": "8c7ba704ceeecfe7386e60e93a9ba9c2a93bc90b39cd1fe7e32b90c34f29a4e2", "spec/v1.9/conformance-badges.md": "1837103fa0f19f825413869a1d2415b3122afca09b0b58511ddef5dc5b1df05d", - "spec/v1.9/conformance-test-suite.md": "83a956029b76ed37e957909af97465d369fda5abb8417b14e10e6fbed0551970", + "spec/v1.9/conformance-test-suite.md": "8f995f3944047ef74695e4b27f3271d5548678de728afa4565a7d305834e7934", "spec/v1.9/iicp-billing-extension.md": "e4a29fc1af8762988b340c060e0b327df1172a6af3ae7524c81c171e4dd30018", "spec/v1.9/iicp-cbor-wire.md": "2b21cfbf9de195529c6113b9717db243f1aef71a24f5daeab1d896c8c644b3b8", - "spec/v1.9/iicp-confidentiality.md": "58c9407dfcf1546f7b37eeff7786eca683695f484a3fae4366b01b1a72ea31d2", + "spec/v1.9/iicp-confidentiality.md": "af4df2a42a37b840ec907ad6de3f00bf02fb3bc6530080c0f43e90abab769229", "spec/v1.9/iicp-cooperative-inference.md": "4f35a608f3c2a7e60398dc36f365abdccbb5da89f521ea6aeb73ba6886c85a6c", - "spec/v1.9/iicp-core.md": "608f0704f7965635c821653794b89493f020a32a0d43c175f3d34c5e83b57ad5", + "spec/v1.9/iicp-core.md": "9731eb9556af07d8c775dd14bba0cc24aa705934801570fdbeaa5d426648bc97", "spec/v1.9/iicp-deployment-provenance.md": "ee7f67221bbfceaf2a096037b488836699adbfb5ab9a18f17d10734dc4b5f03f", "spec/v1.9/iicp-dir.md": "addb16df6265829f882c0d0d2395aa28a71fb5b2c6fc925de3e641f4bfdf04c2", "spec/v1.9/iicp-extensions.md": "c1e0443c2e365abe54c7503dcdeb59a1efdc25d48faafee4429e4aed13f87ce9", "spec/v1.9/iicp-federated-directory.md": "ebb7c237111da0c3e5baa376426ea1b3720b33fe76bc894fda3fcbba5355f3f6", "spec/v1.9/iicp-framing.md": "97e62a411b989f72d097b44bebfb5b8349f48315cec9bf7bb324d17462e2629c", - "spec/v1.9/iicp-identity-slot.md": "9c993178135f5e4a341c7f1cec36e27a9d26573f9dba35b215d9ef63132d7f9c", + "spec/v1.9/iicp-identity-slot.md": "837342eb79ef6be07b93f1a6b8041accfa23fd6a9bf858cafd4470d97d70f14c", "spec/v1.9/iicp-mcp-binding.md": "eac9dce25ab74ed7685a05b0c9dbb286e8c0b5fef96c80e51b10109d72fcf6c6", "spec/v1.9/iicp-provider-admission-profile.md": "5ae8f4ff485fe939e7d61c405ea1209ea63125f9a3e048bda0440bd552e9f364", - "spec/v1.9/iicp-recognition.md": "5dd65bc65236eeb3370f969d60dcb59c51c57695a2a07fec2b7abce912c32eff", + "spec/v1.9/iicp-recognition.md": "d606fc6d5324bc8dfceba4185b135caca9ff23607003239952cebfec3af8761b", "spec/v1.9/iicp-sdk-request-projection-profile.md": "cf90a3938547a33a9bdac0c6c213cfab002af36b5f9f729a38135af2a6e336bd", - "spec/v1.9/iicp-semantics.md": "9bcd018afa0fa4441a930c037b491b4e7cb1d111eb74463bd496ba34e84ee0a8", + "spec/v1.9/iicp-semantics.md": "4068f30dce784e36a4e47886709512a6a6eb37eed2c3cb3df7ec0aae2fb421c2", "spec/v1.9/iicp-service-lifecycle-profile.md": "e825fc5afbeeae0d7b8ef33993a95ea333ee3545bd484f9ca6cdcb90ececd2fa", - "spec/v1.9/iicp-telemetry.md": "4fbb2eb32654186c0f05d749261795635e7051f5d07ee52beedb6715cb977f9d", - "spec/v1.9/iicp-v1.5-draft.md": "b4966af81bd9a7e0318144346a308591e7a2e67170c98c823d23981f50f9b625", - "spec/v1.9/iicp-v1.5-overview.md": "012f693a7848ad7755e7688da676c36d793a75e56e4acecbd7d6a0ae18b7f658", + "spec/v1.9/iicp-telemetry.md": "61154f93263f6af940748090ef7ec6e32fade9bc6afd6b33ce1b700bbf18c5af", + "spec/v1.9/iicp-v1.5-draft.md": "00a07655af18fdc414b80a01326e1a4f0e11069552f1694f023a0e9ff0120447", + "spec/v1.9/iicp-v1.5-overview.md": "5dea602f6dbf6c320240ea5995c028016356888f4a2d4a3d4a9f08292f384d0c", "spec/v1.9/node-capability-format.md": "9dfb7e20ed011439119fcf00e3d37358b7d92ffff63bbb66b9f65e83e743925e", "spec/v1.9/replica-lifecycle-contract-v1.json": "9ae2e3536891c3488a2b4d04e543364359a2b9a2c389203ece0eaca1a341b541", "spec/v1.9/validation-methodology.md": "78693a12a47ed74e72db6b27d23e956bca9a00544ab8637ebebeeb827e39f635", - "standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md": "5e0837bce935a1480ebbc37007bcce9cc117bade8235f18644e6021dd69c2ff4", + "standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md": "4b6f59bf2ba6d8049404cc97a0fe420b68a751d62589162fdd127e0db7e84962", "standards/SUBMISSION_GOVERNANCE_DECISION.md": "ded4b83c2c2ce76a3d2a973bfc36cf689f056c14c26b2ec74076526c349f3d79", "standards/security-considerations-coverage-v1.json": "c917c578a146cc2feaf6c2e8a0c73259646065f480d00fff2c78e7a8282cbdce", "standards/submission-governance-decision-v1.json": "310b377519cddebdf0e904bba895df32449a94ecb6950dbddbcd8656b6207409", @@ -138,18 +146,19 @@ "tools/check_clean_room_interoperability_record.py": "eed5d9a0d5eba295a3e7d5069cad2b526dad5983d3c82dc8a84cc1be1c3510f5", "tools/check_conformance_version_truth.py": "c2885643f167644b657302714999d7b102b087c4f2b7ca9cdd855804ce40ac08", "tools/check_e050_client_credential_lifecycle.py": "7bd5257ed48a9215b9f3fb2679868efd4bc53ae89e2d74b98d00b8a04e436362", - "tools/check_external_participation_campaign.py": "c3c9523008987bf210e14e62d4fcbf78c71826fe0b8c55a234778fcbaac79fcd", + "tools/check_external_participation_campaign.py": "5ee6bee238bee6149ffa28eef2ec48a8715fbd048780d33119329a751ce5e9d9", "tools/check_identity_evidence_layering.py": "6ec6e752944db65559867490f7e7479875380692760356f7f585effa90526a07", "tools/check_intent_registry.py": "58103bc020f2609ead76a4d52db7b6cebdabbba6a5f01ccb909c9b0dd154855f", "tools/check_intent_registry_schema.py": "d868bb821d4dc278dbddefe8e449033d9f20c4e243c1843142e2047ab0429c8c", "tools/check_newcomer_validation_record.py": "4cf42b3059a82066c7276f69be11b991994280d58e9799eebcddc0fc661cacd9", "tools/check_operator_onboarding_recovery.py": "c7b8023b918a3ba936b4dbd7f41760b6d2f798daa399140b335ff0f63b0a5536", + "tools/check_public_artifact_closure.py": "a88053b9f673a91694eb3c31593ab693971f4f93d7836c458e90c0a298a6ec05", "tools/check_public_evidence_access.py": "11dbe24705404e73ebe9fddb54f22bcd5facd977a06e374f8718bebd87fa60f5", "tools/check_public_prose.py": "4b0fa3becd2c71af7a1a89d72f971988bc019acc3917d7d59b8ead2fafe94657", "tools/check_relay_eligibility_record.py": "b883f0172d895b664f5269dd56448ef02d64a49fadbf55da5704bba8466f3cd8", "tools/check_security_considerations_coverage.py": "182d29f056e1e396d3331a1d1bac66d28d83bb4acf6beb4c785dc16c5acaccfe", "tools/check_signed_message_envelope_boundary.py": "6ff4228e34408681bdcc4485d3470b9a86b7f7b4a4fd5bbf56e830e2fcc53c5b", - "tools/check_spec_release_integrity.py": "a468f623bca4312eda11b420ac4a33e04ebb64a5fd4cfc90f2e71898810a6ca6", + "tools/check_spec_release_integrity.py": "22cc5939e39999be428a90fff188befb95d28378a3969520c8fbae8669a0444d", "tools/check_submission_governance_decision.py": "a249100bf6c2836ea01ceee353fa5c139ecbe0f0b280fe250a86d11137dde9cd", "tools/requirements.txt": "117bb7857e2106917057761be56b51e26df4b9c0e3ebdbcf48a992e94534c6ac", "tools/test_audit_intent_sources.py": "8286e32879fcf48647f00facc8bca1fbf9a460393e9fc607e50440cd1fae063f", @@ -160,13 +169,14 @@ "tools/test_effective_capability_wire_contract.py": "123a7f2de8b72eb39988a79a878ec21941c20be8fe95bb39abb7a8262fe9693d", "tools/test_effective_service_capability_semantics.py": "10573b584aed904687b6e6ad856c55f1585d3001490dbf37b9e7f4179df74b17", "tools/test_environmental_independence_decision.py": "bb6a7690d85262a3670fbc8e27bccdcf60769f4ab19c4cebb8f536dd8ac3659d", - "tools/test_external_participation_campaign.py": "cb1af5dfdf6679fa59da22d02b5756982b0ee0c45c3a4e7f6f42bb4c13a7d125", + "tools/test_external_participation_campaign.py": "1872b43e1c4d357f31cd7eee4c65d9bb44aa600ebf824421151e7417544f0ee6", "tools/test_identifier_registry_architecture.py": "4d06c68cc7bc11d9d3e363b452ded724d70ac479bb7986eeb6615a830b1d90a4", "tools/test_identity_evidence_layering.py": "dd6fddeef0adecd0f82c70a7d3d7a5300855b6f490cb815e4046587634c5410d", "tools/test_intent_payload_fixture.py": "cae5bc663eca3673e90f4a0d0315dab25d15a193d4b8a726b5a4926776fa522f", "tools/test_intent_registry.py": "105ecb1edfc034d0fae433c2c17f16f905d405715d40c521dc1feb124fa146f5", "tools/test_newcomer_validation_record.py": "1342734ce07741bf276ce02a097ddbb7be05970cac60a4c3a2dbc03e25dc54a4", "tools/test_operator_onboarding_recovery.py": "ffd287d990e212ef476740f769159b2c12e8d91654542e21ca369fcd0f57e005", + "tools/test_public_artifact_closure.py": "e3cac4a2ac497a39e6503ac8f251a4f6fcd26eb230dab90fafdb8b3e686e5121", "tools/test_public_evidence_access.py": "44074627fe15a527f339e5d45c233b33b1393310469a59c9bfb92cc3514a4ee1", "tools/test_public_prose.py": "39f8488525192780a4cabda0c3b5641208fb7b27c66044bd464693e740fc505f", "tools/test_relay_eligibility_record.py": "5029125dc6981c4624eaa18631f2e90e54f8a33967e1cc61ea3836928edd6413", diff --git a/standards/REVIEWING.md b/standards/REVIEWING.md new file mode 100644 index 0000000..39b80b1 --- /dev/null +++ b/standards/REVIEWING.md @@ -0,0 +1,70 @@ +# Reviewing IICP standards material + +## Review target + +The current IETF workspace contains an individual Internet-Draft candidate. It +has not been submitted and has no IETF or IANA status. The candidate covers the +peer transport only; directory ranking, credits, federation, cooperative +execution, MCP and deployment-specific NAT traversal are outside its normative +scope. + +Start with: + +1. `standards/ietf/draft-roble-iicp-peer.md`; +2. `standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md`; +3. [`standards/ietf/evidence-matrix.md`](ietf/evidence-matrix.md); +4. `spec/v1.9/iicp-framing.md` and the pinned native-framing fixtures when a + requirement needs implementation context. + +Implementations are evidence, not normative authority. A disagreement between +the candidate and a maintained implementation is a review finding, not an +automatic change to the specification. + +## Reproducible build + +Use the pinned Ruby and Python dependencies: + +```bash +bundle install --gemfile standards/ietf/Gemfile +python3 -m venv .venv-ietf +.venv-ietf/bin/pip install -r standards/ietf/requirements.txt +PATH=".venv-ietf/bin:$PATH" bundle exec --gemfile standards/ietf/Gemfile \ + tools/build_internet_draft.sh +``` + +The build writes XML, plain text and HTML to `build/ietf/`. It also verifies +that the candidate makes no IANA request and does not call port 9484 assigned. + +Create a deterministic review bundle after a successful build: + +```bash +python3 tools/build_standards_review_bundle.py +``` + +The bundle contains the source, rendered formats, evidence matrix, public +security and governance context, and a digest manifest. Building it does not +submit the draft. + +## Reporting a finding + +Open a public issue in `RobLe3/IICP` using the protocol-proposal or +documentation template. Include: + +- the draft section and exact text; +- the competing interpretation; +- the interoperability, security or operational consequence; +- relevant public specification, implementation or test evidence; +- whether the proposed correction is normative or editorial. + +Do not use private implementation history to resolve an ambiguity. Record the +ambiguity so that the public source can be corrected. + +Security vulnerabilities should follow `SECURITY.md` rather than a public +issue. Do not include credentials, task content, private topology or personal +data in review evidence. + +## Status and authority + +Building or reviewing the candidate does not authorize an Internet-Draft +upload, mailing-list post, IANA request, protocol release or deployment. Those +actions require their separately recorded governance decisions. diff --git a/standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md b/standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md index 7cdd9ee..219a96a 100644 --- a/standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md +++ b/standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md @@ -54,9 +54,11 @@ SSRF guards, authenticate providers independently and treat DNS/mDNS records as untrusted bootstrap candidates. Ticketed-dispatch adoption and any retirement of the legacy projection require a separate measured cutover decision. -**Future:** root #612 and profile gate #58. No current document should imply -that all discovery is route-free or that route tickets provide single-use task -admission. +**Future:** public standards gate #58 owns the endpoint-safe route-ticket and +receipt semantics. Deployment-specific retirement of the legacy projection is +an operator decision, not a protocol dependency. No current document should +imply that all discovery is route-free or that route tickets provide +single-use task admission. ## Authentication and authorization @@ -129,9 +131,9 @@ discovery, task, receipt and relay costs. **Implemented evidence:** parser, framing, malformed-input, size, SSRF and timeout cases exist across the conformance suite and maintained components. -**Future:** registration burst and steady-state tuning remains PHP issue #65; -relay production abuse hardening remains root #524. Neither absence authorizes -unbounded defaults. +**Future:** registration burst and steady-state tuning remains PHP directory +issue #65; the public relay eligibility work remains IICP issue #59. Neither +absence authorizes unbounded defaults. ## Endpoint exposure, NAT and local discovery diff --git a/standards/STANDARDS_READINESS.md b/standards/STANDARDS_READINESS.md index 9f0ea3b..a152133 100644 --- a/standards/STANDARDS_READINESS.md +++ b/standards/STANDARDS_READINESS.md @@ -13,8 +13,8 @@ If the fixed-port evidence gate passes, the first candidate is service name `iicp`, port 9484, TCP only, through RFC 6335 Expert Review. Port 9484 is currently unassigned. It is not reserved for IICP. -Before applying, issue RobLe3/iicp.network#669 must compare the dedicated port -with: +Before applying, public IICP issue #42 must record evidence comparing the +dedicated port with: - signed route metadata carrying a dynamic port; - DNS SRV, SVCB or HTTPS discovery; diff --git a/standards/ietf/README.md b/standards/ietf/README.md index 3b1d12f..22bd948 100644 --- a/standards/ietf/README.md +++ b/standards/ietf/README.md @@ -3,6 +3,11 @@ This directory contains an individual-draft candidate. It is not an IETF submission and does not imply IETF or IANA endorsement. +Review scope, evidence boundaries and ambiguity reporting are documented in +[`../REVIEWING.md`](../REVIEWING.md). The informative +[`evidence-matrix.md`](evidence-matrix.md) maps the candidate's requirement +classes to public specification, fixture and implementation evidence. + Build locally: ```bash @@ -14,4 +19,6 @@ PATH=".venv-ietf/bin:$PATH" bundle exec --gemfile standards/ietf/Gemfile \ ``` Generated files are written to `build/ietf/` and are not release artifacts -unless the specification release procedure explicitly includes them. +unless the specification release procedure explicitly includes them. After a +successful build, `python3 tools/build_standards_review_bundle.py` creates a +deterministic, self-contained reviewer archive without submitting the draft. diff --git a/standards/ietf/draft-roble-iicp-peer.md b/standards/ietf/draft-roble-iicp-peer.md index d9c2898..684bea7 100644 --- a/standards/ietf/draft-roble-iicp-peer.md +++ b/standards/ietf/draft-roble-iicp-peer.md @@ -221,3 +221,7 @@ No UDP port, ALPN identifier, media type, or CBOR tag is requested here. The public IICP specifications, conformance fixtures, and maintained language implementations informed this draft. Those implementations are evidence and are not normative authority. + +An informative, version-controlled evidence matrix and independent review +instructions are published with the draft source. They are review aids rather +than part of this protocol definition. diff --git a/standards/ietf/evidence-matrix.md b/standards/ietf/evidence-matrix.md new file mode 100644 index 0000000..11a3fa7 --- /dev/null +++ b/standards/ietf/evidence-matrix.md @@ -0,0 +1,77 @@ +# IICP peer-transport evidence matrix + +**Status:** informative review aid +**Draft:** `draft-roble-iicp-peer` +**Protocol baseline:** IICP 1.9 wire compatibility; suite release 1.10.13 + +This matrix connects each requirement class in the peer-transport candidate to +public specifications, fixtures and implementation tests. The Internet-Draft +remains the text under review. An implementation or test can show that a rule +is implementable, but it cannot redefine the rule. + +## Evidence classes + +| Draft section | Requirement class | Public protocol evidence | Executable or implementation evidence | +| --- | --- | --- | --- | +| Protocol Scope | Separation of route selection from task execution | [`iicp-core.md`](../../spec/v1.9/iicp-core.md), [`iicp-framing.md` §13.5](../../spec/v1.9/iicp-framing.md#135-directory-control-plane-constraint) | The maintained SDK repositories expose peer invocation independently of the PHP and Rust directory repositories; the public repository roles are listed in [`public-repositories.json`](../../ecosystem/public-repositories.json). | +| Connection Establishment | TLS, peer authentication and route distrust | [`iicp-framing.md` §9](../../spec/v1.9/iicp-framing.md#9-security-considerations), [`iicp-core.md`](../../spec/v1.9/iicp-core.md) | Consumer/provider security and negative-path tests in the [Rust](https://github.com/RobLe3/iicp-client-rust), [Python](https://github.com/RobLe3/iicp-client-python) and [TypeScript](https://github.com/RobLe3/iicp-client-typescript) SDKs. | +| Frame Format | Twelve-octet header, network-order length and allocation limits | [`iicp-framing.md` §§1-2](../../spec/v1.9/iicp-framing.md#1-binary-frame-format) | Canonical [`native-framing-v1.json`](../../research/native-ai-infrastructure/fixtures/native-framing-v1.json), its [digest manifest](../../research/native-ai-infrastructure/fixtures/native-framing-fixture-manifest-v1.json), and [`check_native_framing_fixtures.py`](../../tools/check_native_framing_fixtures.py). | +| Messages | INIT/ACK, CALL/RESPONSE, PING/PONG and CLOSE behavior | [`iicp-framing.md` §§3-4 and 8](../../spec/v1.9/iicp-framing.md#3-message-type-table) | The shared native-framing fixture is consumed by all three maintained SDKs through their `native_framing_fixture` tests. | +| CBOR Encoding | Deterministic CBOR, bounded schemas and prohibited indefinite lengths | [`iicp-cbor-wire.md`](../../spec/v1.9/iicp-cbor-wire.md), [`iicp-framing.md` §4](../../spec/v1.9/iicp-framing.md#4-cbor-payload-encoding) | Canonical framing fixture plus SDK-local decoding/validation tests. `run_native_framing_conformance.sh` verifies byte-identical fixture copies before running those tests. | +| Timeouts, Cancellation, and Replay | Timeout is not cancellation; task identity is scoped; conflicting reuse fails | [`iicp-service-lifecycle-profile.md`](../../spec/v1.9/iicp-service-lifecycle-profile.md), [`iicp-framing.md` §4.4](../../spec/v1.9/iicp-framing.md#44-response-message-schema-0x06) | `native_call_identity` and `native_response_sequence` tests in each maintained SDK. Confirmed cancellation remains outside the candidate unless a lifecycle profile is negotiated. | +| Error Handling | Distinct malformed-input classes, pre-dispatch rejection and bounded diagnostics | [`iicp-core.md` §7](../../spec/v1.9/iicp-core.md), [`iicp-framing.md` §§9.6-9.7](../../spec/v1.9/iicp-framing.md#96-malformed-frame-handling--disposition-table) | Parser and framing negative tests in maintained SDKs; release-integrity and fixture checks in this repository. | +| Security Considerations | Downgrade, replay, endpoint, relay and resource-exhaustion boundaries | [`iicp-core.md`](../../spec/v1.9/iicp-core.md), [`iicp-framing.md` §9](../../spec/v1.9/iicp-framing.md#9-security-considerations), [`privacy-adversary-and-trust-model.md`](../../docs/security/privacy-adversary-and-trust-model.md) | [`SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md`](../SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md) records implemented, experimental and future evidence separately. | +| Privacy Considerations | Directory bypass, executor visibility and metadata leakage | [`iicp-confidentiality.md`](../../spec/v1.9/iicp-confidentiality.md), [`privacy-adversary-and-trust-model.md`](../../docs/security/privacy-adversary-and-trust-model.md) | IICP-CX and relay tests are supporting project evidence only. They do not change the candidate's statement that an ordinary selected executor sees plaintext. | +| IANA Considerations | No current assignment or registration claim | [`iicp-framing.md` §11](../../spec/v1.9/iicp-framing.md#11-iana-considerations), [`STANDARDS_READINESS.md`](../STANDARDS_READINESS.md) | [`build_internet_draft.sh`](../../tools/build_internet_draft.sh) fails if the source omits the no-request statement or describes TCP port 9484 as assigned. | + +## Path and platform coverage + +### Direct and relay-carried paths + +The peer payload normally travels directly between consumer and provider. An +explicitly selected relay may carry the same payload, but it is then on the +transport path. Relay use does not move the directory onto the payload path and +does not authenticate the provider. End-to-end payload confidentiality through +a relay requires a separately negotiated confidentiality mechanism whose keys +remain outside relay control. + +Relay operation is experimental and is not used as evidence that the minimal +peer transport is independently deployed or operationally stable. + +### Browser limitation + +The browser implementation is public and useful interoperability evidence for +HTTP/Web platform mappings. A normal browser does not expose a raw TCP socket +API, so the browser node is **not** evidence for the native TLS-over-TCP framing +path described by this candidate. Browser support does not change the native +transport requirements. + +### Maintained implementation set + +The Rust, Python and TypeScript SDKs are maintained by the same project. Their +agreement is cross-language parity evidence, not an independent implementation. +The PHP and Rust directory projects implement the control plane and are not +additional peer-transport implementations. The current public component list +and roles are machine-readable in [`public-repositories.json`](../../ecosystem/public-repositories.json). + +## Reproduction + +From a clean checkout with the documented toolchains: + +```bash +python3 tools/check_native_framing_fixtures.py \ + --copy ../iicp-client-rust/tests/fixtures/native-framing-v1.json \ + --copy ../iicp-client-python/tests/fixtures/native-framing-v1.json \ + --copy ../iicp-client-typescript/tests/fixtures/native-framing-v1.json +./tools/run_native_framing_conformance.sh + +bundle install --gemfile standards/ietf/Gemfile +python3 -m venv .venv-ietf +.venv-ietf/bin/pip install -r standards/ietf/requirements.txt +PATH=".venv-ietf/bin:$PATH" bundle exec --gemfile standards/ietf/Gemfile \ + tools/build_internet_draft.sh +``` + +The review-bundle builder packages the source, rendered XML/text/HTML, this +matrix and the public review dependencies with a digest manifest. It does not +submit the draft or make an IANA request. diff --git a/tools/build_standards_review_bundle.py b/tools/build_standards_review_bundle.py new file mode 100644 index 0000000..d75481b --- /dev/null +++ b/tools/build_standards_review_bundle.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +"""Build a deterministic, self-contained review bundle for the IICP peer draft. + +The rendered XML, text and HTML must already have been produced by the pinned +Internet-Draft build. This tool packages them with the source, public evidence +and a digest manifest. It never uploads or submits the draft. +""" +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path +import subprocess +import zipfile + + +ROOT = Path(__file__).resolve().parents[1] +DEFAULT_SOURCE = ROOT / "standards/ietf/draft-roble-iicp-peer.md" +DEFAULT_RENDERED = ROOT / "build/ietf" +DEFAULT_OUTPUT = ROOT / "build/standards-review" +ZIP_TIME = (2026, 8, 15, 0, 0, 0) + +PUBLIC_INPUTS = ( + "LICENSE", + "SECURITY.md", + "CONTRIBUTING.md", + "CONTINUATION.md", + "docs/governance/public-artifact-boundary.md", + "docs/security/privacy-adversary-and-trust-model.md", + "ecosystem/public-repositories.json", + "standards/REVIEWING.md", + "standards/STANDARDS_READINESS.md", + "standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md", + "standards/ietf/README.md", + "standards/ietf/evidence-matrix.md", +) + + +def sha256_bytes(content: bytes) -> str: + return hashlib.sha256(content).hexdigest() + + +def zip_write(archive: zipfile.ZipFile, name: str, content: bytes) -> None: + info = zipfile.ZipInfo(name, ZIP_TIME) + info.compress_type = zipfile.ZIP_DEFLATED + info.external_attr = 0o100644 << 16 + archive.writestr(info, content, compresslevel=9) + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--source", type=Path, default=DEFAULT_SOURCE) + parser.add_argument("--rendered-dir", type=Path, default=DEFAULT_RENDERED) + parser.add_argument("--output-dir", type=Path, default=DEFAULT_OUTPUT) + args = parser.parse_args() + + source = args.source.resolve() + rendered = args.rendered_dir.resolve() + output = args.output_dir.resolve() + base = source.stem + rendered_files = [rendered / f"{base}.{suffix}" for suffix in ("xml", "txt", "html")] + + missing = [str(path) for path in [source, *rendered_files] if not path.is_file()] + missing.extend(relative for relative in PUBLIC_INPUTS if not (ROOT / relative).is_file()) + if missing: + raise SystemExit("review bundle input missing:\n- " + "\n- ".join(missing)) + + subprocess.run( + ["python3", str(ROOT / "tools/check_public_artifact_closure.py")], + cwd=ROOT, + check=True, + ) + + members: dict[str, bytes] = { + relative: (ROOT / relative).read_bytes() for relative in PUBLIC_INPUTS + } + source_name = f"standards/ietf/{source.name}" + members[source_name] = source.read_bytes() + for path in rendered_files: + members[f"rendered/{path.name}"] = path.read_bytes() + + manifest = { + "schema": "iicp.standards-review-bundle.v1", + "status": "individual-draft-candidate; not submitted", + "draft": base, + "files": { + name: sha256_bytes(content) for name, content in sorted(members.items()) + }, + } + members["SHA256SUMS.json"] = ( + json.dumps(manifest, indent=2, sort_keys=True) + "\n" + ).encode("utf-8") + + output.mkdir(parents=True, exist_ok=True) + bundle = output / f"{base}-review-bundle.zip" + prefix = f"{base}-review-bundle/" + with zipfile.ZipFile(bundle, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as zf: + for name, content in sorted(members.items()): + zip_write(zf, prefix + name, content) + + digest = sha256_bytes(bundle.read_bytes()) + bundle.with_suffix(".zip.sha256").write_text( + f"{digest} {bundle.name}\n", encoding="ascii" + ) + print(f"built {bundle}") + print(f"sha256 {digest}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/check_external_participation_campaign.py b/tools/check_external_participation_campaign.py index 952ca7e..f1a4aa6 100644 --- a/tools/check_external_participation_campaign.py +++ b/tools/check_external_participation_campaign.py @@ -15,7 +15,6 @@ "newcomer-validation", "linux-systemd-operator", "relay-operator", - "qualified-eu-review", "standards-governance", } LOCAL_RECORDS = { @@ -38,7 +37,7 @@ def validate(record: dict, root: Path = ROOT) -> list[str]: lanes = record.get("lanes", []) ids = [lane.get("id") for lane in lanes] if set(ids) != LANES or len(ids) != len(set(ids)): - errors.append("campaign must contain the six unique participation lanes") + errors.append("campaign must contain the five unique public participation lanes") for lane in lanes: lane_id = lane.get("id") for field in ("tracker", "participant", "fixed_inputs", "record", "validator", "submission"): @@ -73,7 +72,7 @@ def main() -> int: for error in errors: print(f"ERROR: {error}") return 1 - print("external participation campaign valid: 6 awaiting-participant lanes") + print("external participation campaign valid: 5 awaiting-participant lanes") return 0 diff --git a/tools/check_public_artifact_closure.py b/tools/check_public_artifact_closure.py new file mode 100644 index 0000000..3efe06b --- /dev/null +++ b/tools/check_public_artifact_closure.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +"""Verify that public release and standards inputs have no private dependencies.""" + +from __future__ import annotations + +import argparse +import json +import re +import subprocess +import sys +from dataclasses import dataclass +from pathlib import Path +from urllib.parse import urlsplit + + +ROOT = Path(__file__).resolve().parents[1] +MANIFEST = ROOT / "spec/v1.9/release-integrity-manifest.json" +REVIEW_INPUTS = { + "standards/REVIEWING.md", + "standards/STANDARDS_READINESS.md", + "standards/SUBMISSION_GOVERNANCE_DECISION.md", + "standards/SECURITY_PRIVACY_OPERATIONAL_CONSIDERATIONS_2026-08-13.md", + "standards/ietf/README.md", + "standards/ietf/draft-roble-iicp-peer.md", + "standards/ietf/evidence-matrix.md", + "research/RESEARCH.md", +} +PATTERN_EXEMPTIONS = { + "docs/governance/public-artifact-boundary.md", + # Published negative vector: the generic /Users/operator path must remain + # byte-stable because released directory parity contracts pin its digest. + "fixtures/directory-implementation-metadata-v1.json", + "tools/check_public_artifact_closure.py", + "tools/test_public_artifact_closure.py", +} +TEXT_SUFFIXES = {".md", ".json", ".py", ".toml", ".yml", ".yaml", ".txt"} +PRIVATE_REPOSITORY = re.compile( + r"(?:https://github\.com/RobLe3/(?:iicp\.network|iicp-network-ops|iicp-network-internal)" + r"|(? set[str]: + manifest = json.loads((root / MANIFEST.relative_to(ROOT)).read_text(encoding="utf-8")) + return set(manifest["files"]) | {"spec/v1.9/release-integrity-manifest.json"} + + +def tracked_public_paths(root: Path) -> set[str]: + """Return tracked text artifacts for the optional whole-repository audit.""" + result = subprocess.run( + ["git", "ls-files", "-z", "--cached", "--others", "--exclude-standard"], + cwd=root, + check=True, + capture_output=True, + ) + paths: set[str] = set() + for raw in result.stdout.split(b"\0"): + if not raw: + continue + relative = raw.decode("utf-8") + if Path(relative).suffix.lower() in TEXT_SUFFIXES: + paths.add(relative) + return paths + + +def is_public_external(target: str) -> bool: + parsed = urlsplit(target) + return parsed.scheme in {"http", "https", "mailto", "urn"} or target.startswith("#") + + +def local_target_exists(source: Path, target: str, root: Path) -> bool: + clean = target.split("#", 1)[0].split("?", 1)[0] + if not clean or is_public_external(target): + return True + if clean.startswith("/"): + return False + return (source.parent / clean).resolve().is_relative_to(root.resolve()) and (source.parent / clean).resolve().exists() + + +def validate(root: Path = ROOT, paths: set[str] | None = None) -> list[Finding]: + selected = paths if paths is not None else release_paths(root) | REVIEW_INPUTS + findings: list[Finding] = [] + for relative in sorted(selected): + source = root / relative + if not source.is_file(): + findings.append(Finding(relative, 0, "required public artifact is missing")) + continue + if source.suffix.lower() not in TEXT_SUFFIXES: + continue + text = source.read_text(encoding="utf-8", errors="replace") + for line_number, line in enumerate(text.splitlines(), 1): + if relative not in PATTERN_EXEMPTIONS: + if PRIVATE_REPOSITORY.search(line): + findings.append(Finding(relative, line_number, "depends on or names a private repository")) + if INTERNAL_PATH.search(line): + findings.append(Finding(relative, line_number, "depends on an unavailable internal project path")) + if WORKSTATION_PATH.search(line): + findings.append(Finding(relative, line_number, "contains a workstation-local path")) + if relative.startswith("research/") and PRIVATE_METHOD_MARKER.search(line): + findings.append(Finding(relative, line_number, "exposes private development-method provenance")) + if source.suffix.lower() == ".md": + for match in MARKDOWN_LINK.finditer(line): + target = match.group(1).strip("<>") + if not local_target_exists(source, target, root): + findings.append(Finding(relative, line_number, f"unresolved local link: {target}")) + return findings + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("paths", nargs="*", help="optional repository-relative paths") + parser.add_argument( + "--all-public", + action="store_true", + help="scan every tracked public text artifact, not only release/review inputs", + ) + args = parser.parse_args() + if args.paths and args.all_public: + parser.error("paths and --all-public are mutually exclusive") + selected = tracked_public_paths(ROOT) if args.all_public else (set(args.paths) if args.paths else None) + findings = validate(ROOT, selected) + if findings: + for finding in findings: + print(f"{finding.path}:{finding.line}: {finding.message}", file=sys.stderr) + return 1 + count = len(selected if selected is not None else release_paths(ROOT) | REVIEW_INPUTS) + print(f"public artifact closure passed: {count} self-contained artifacts") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/check_spec_release_integrity.py b/tools/check_spec_release_integrity.py index ca96b08..475cb1e 100755 --- a/tools/check_spec_release_integrity.py +++ b/tools/check_spec_release_integrity.py @@ -38,9 +38,20 @@ def main() -> int: errors.append(f"missing required file: {relative}") elif digest(path) != expected: errors.append(f"digest mismatch: {relative}") + from check_public_artifact_closure import validate as validate_public_artifacts + errors.extend( + f"public artifact closure: {finding.path}:{finding.line}: {finding.message}" + for finding in validate_public_artifacts(ROOT) + ) required = { + "LICENSE", + "GOVERNANCE.md", + "SECURITY.md", + "CONTRIBUTING.md", + "CONTINUATION.md", "CHANGELOG.md", "ecosystem/repositories.json", + "ecosystem/public-repositories.json", "SPEC_STATUS.md", "VERSIONING.md", "registry/intents.json", @@ -58,6 +69,8 @@ def main() -> int: "research/native-ai-infrastructure/fixtures/service-profiles-v1.json", "tools/test_service_lifecycle_fixture.py", "docs/operator-onboarding-recovery.md", + "docs/governance/public-artifact-boundary.md", + "docs/security/privacy-adversary-and-trust-model.md", "docs/architecture/environmental-independence-and-extension-architecture.md", "docs/architecture/environmental-independence-v1.json", "tools/test_environmental_independence_decision.py", @@ -105,6 +118,8 @@ def main() -> int: "tools/test_signed_message_envelope_boundary.py", "tools/check_public_evidence_access.py", "tools/test_public_evidence_access.py", + "tools/check_public_artifact_closure.py", + "tools/test_public_artifact_closure.py", } missing_pins = sorted(required - set(manifest["files"])) if missing_pins: diff --git a/tools/generate_implementations.py b/tools/generate_implementations.py index 65c3707..3bcb0e8 100644 --- a/tools/generate_implementations.py +++ b/tools/generate_implementations.py @@ -11,7 +11,8 @@ OUTPUT = ROOT / "IMPLEMENTATIONS.md" CURRENT_JSON = ROOT / "ecosystem" / "current-versions.json" CURRENT_MARKDOWN = ROOT / "ecosystem" / "CURRENT_VERSIONS.md" -VISIBILITIES = {"public", "private"} +PUBLIC_JSON = ROOT / "ecosystem" / "public-repositories.json" +VISIBILITIES = {"public"} LIFECYCLES = { "active", "experimental", @@ -43,18 +44,15 @@ def render(data: dict) -> str: "", "This index is generated from `ecosystem/repositories.json`. Repositories are", "independently versioned; they are logical members of the IICP ecosystem, not", - "Git submodules. Visibility describes source access, not protocol maturity.", + "Git submodules. Private operations, website and development-method sources are", + "not public build, conformance or governance dependencies.", "", "| Component | Authority | Language | Visibility | Lifecycle | Release |", "|---|---|---|---|---|---|", ] for item in data["repositories"]: release = item["release"] or "—" - component = ( - f"[{item['name']}]({item['url']})" - if item["visibility"] == "public" - else f"{item['name']} (source private)" - ) + component = f"[{item['name']}]({item['url']})" lines.append( f"| {component} | {item['authority']} | " f"{item['language']} | {item['visibility']} | {item['lifecycle']} | {release} |" @@ -74,6 +72,29 @@ def render(data: dict) -> str: return "\n".join(lines) +def public_projection(data: dict) -> dict: + """Return the stable machine-readable public repository handoff.""" + fields = ( + "id", + "name", + "url", + "authority", + "language", + "protocol", + "lifecycle", + "release", + "package", + ) + return { + "schema": "iicp.public-repositories.v1", + "generated_at": data["generated_at"], + "repositories": [ + {field: item[field] for field in fields if field in item} + for item in data["repositories"] + ], + } + + def current_projection(data: dict) -> dict: components = { item["id"]: { @@ -133,16 +154,20 @@ def main() -> None: data = load() rendered = render(data) projection = current_projection(data) + repositories_projection = public_projection(data) rendered_projection = json.dumps(projection, indent=2, sort_keys=True) + "\n" + rendered_repositories = json.dumps(repositories_projection, indent=2, sort_keys=True) + "\n" rendered_current_markdown = render_current_markdown(projection) if "--check" in __import__("sys").argv: assert OUTPUT.exists() and OUTPUT.read_text() == rendered, "IMPLEMENTATIONS.md is stale" assert CURRENT_JSON.exists() and CURRENT_JSON.read_text() == rendered_projection, "current-versions.json is stale" assert CURRENT_MARKDOWN.exists() and CURRENT_MARKDOWN.read_text() == rendered_current_markdown, "CURRENT_VERSIONS.md is stale" + assert PUBLIC_JSON.exists() and PUBLIC_JSON.read_text() == rendered_repositories, "public-repositories.json is stale" else: OUTPUT.write_text(rendered) CURRENT_JSON.write_text(rendered_projection) CURRENT_MARKDOWN.write_text(rendered_current_markdown) + PUBLIC_JSON.write_text(rendered_repositories) if __name__ == "__main__": diff --git a/tools/protocol_integrity_analysis.py b/tools/protocol_integrity_analysis.py index ab5dbae..bdea7af 100644 --- a/tools/protocol_integrity_analysis.py +++ b/tools/protocol_integrity_analysis.py @@ -17,6 +17,8 @@ from enum import Enum import random import statistics +import argparse +from pathlib import Path class MessageType(Enum): INIT = 0x01 @@ -569,10 +571,19 @@ def generate_methodology_explanation(): """ if __name__ == "__main__": + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--output", + type=Path, + default=Path("build/validation_results_v1.4.2.json"), + help="JSON result path (default: build/validation_results_v1.4.2.json)", + ) + args = parser.parse_args() results = create_performance_validation_report() # Save results to JSON for documentation - with open('/Users/roble/Library/Mobile Documents/com~apple~CloudDocs/Blog Article/IICP/validation_results_v1.4.2.json', 'w') as f: + args.output.parent.mkdir(parents=True, exist_ok=True) + with args.output.open('w', encoding='utf-8') as f: json.dump({ 'timestamp': time.time(), 'version': '1.4.2', @@ -591,5 +602,5 @@ def generate_methodology_explanation(): 'methodology': results['methodology'] }, f, indent=2) - print(f"\n📄 Results saved to validation_results_v1.4.2.json") - print("\n✅ Performance validation complete!") \ No newline at end of file + print(f"\n📄 Results saved to {args.output}") + print("\n✅ Performance validation complete!") diff --git a/tools/research-requirements.txt b/tools/research-requirements.txt new file mode 100644 index 0000000..614713f --- /dev/null +++ b/tools/research-requirements.txt @@ -0,0 +1,4 @@ +# Optional dependencies for the historical simulation and validation scripts. +# Normative schema, fixture and release checks use tools/requirements.txt. +numpy>=2.2,<3 +matplotlib>=3.10,<4 diff --git a/tools/test_external_participation_campaign.py b/tools/test_external_participation_campaign.py index 156d6f0..3de1f49 100644 --- a/tools/test_external_participation_campaign.py +++ b/tools/test_external_participation_campaign.py @@ -15,7 +15,7 @@ def test_repository_campaign_is_valid(self) -> None: def test_missing_lane_fails(self) -> None: record = copy.deepcopy(self.record) record["lanes"].pop() - self.assertTrue(any("six unique" in error for error in validate(record))) + self.assertTrue(any("five unique" in error for error in validate(record))) def test_result_or_consent_claim_fails(self) -> None: record = copy.deepcopy(self.record) diff --git a/tools/test_public_artifact_closure.py b/tools/test_public_artifact_closure.py new file mode 100644 index 0000000..628f7ca --- /dev/null +++ b/tools/test_public_artifact_closure.py @@ -0,0 +1,92 @@ +from __future__ import annotations + +import json +from pathlib import Path +import subprocess +import tempfile +import unittest + +from check_public_artifact_closure import validate + + +ROOT = Path(__file__).resolve().parents[1] + + +class PublicArtifactClosureTest(unittest.TestCase): + def make_root(self) -> Path: + temporary = tempfile.TemporaryDirectory() + self.addCleanup(temporary.cleanup) + root = Path(temporary.name) + (root / "spec/v1.9").mkdir(parents=True) + (root / "spec/v1.9/release-integrity-manifest.json").write_text( + json.dumps({"files": {"doc.md": "unused"}}), encoding="utf-8" + ) + return root + + def test_public_relative_and_external_links_pass(self) -> None: + root = self.make_root() + (root / "target.md").write_text("public\n", encoding="utf-8") + (root / "doc.md").write_text( + "[local](target.md) [RFC](https://www.rfc-editor.org/rfc/rfc8126.html)\n", + encoding="utf-8", + ) + self.assertEqual(validate(root, {"doc.md"}), []) + + def test_private_repository_is_rejected(self) -> None: + root = self.make_root() + (root / "doc.md").write_text( + "See https://github.com/RobLe3/iicp.network/issues/1\n", encoding="utf-8" + ) + self.assertIn("private repository", validate(root, {"doc.md"})[0].message) + + def test_internal_and_workstation_paths_are_rejected(self) -> None: + root = self.make_root() + (root / "doc.md").write_text( + "Use `project/SECRET.md` from /Users/alice/work/iicp.\n", encoding="utf-8" + ) + messages = [finding.message for finding in validate(root, {"doc.md"})] + self.assertTrue(any("internal project path" in message for message in messages)) + self.assertTrue(any("workstation-local" in message for message in messages)) + + def test_unresolved_local_link_is_rejected(self) -> None: + root = self.make_root() + (root / "doc.md").write_text("[missing](missing.md)\n", encoding="utf-8") + self.assertIn("unresolved local link", validate(root, {"doc.md"})[0].message) + + def test_published_negative_path_vector_is_explicitly_exempt(self) -> None: + root = self.make_root() + relative = "fixtures/directory-implementation-metadata-v1.json" + (root / "fixtures").mkdir() + (root / relative).write_text( + '{"implementation_name":"/Users/operator/private-build"}\n', + encoding="utf-8", + ) + self.assertEqual([], validate(root, {relative})) + + def test_research_index_rejects_private_method_marker(self) -> None: + root = self.make_root() + (root / "research").mkdir() + (root / "research/RESEARCH.md").write_text("Maintained by FORGE\n", encoding="utf-8") + self.assertIn( + "private development-method provenance", + validate(root, {"research/RESEARCH.md"})[0].message, + ) + + def test_all_public_option_cannot_be_combined_with_paths(self) -> None: + result = subprocess.run( + [ + "python3", + str(ROOT / "tools/check_public_artifact_closure.py"), + "--all-public", + "README.md", + ], + cwd=ROOT, + capture_output=True, + text=True, + ) + self.assertEqual(2, result.returncode) + self.assertIn("mutually exclusive", result.stderr) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/test_spec_release.py b/tools/test_spec_release.py index cfd1578..af58d6d 100644 --- a/tools/test_spec_release.py +++ b/tools/test_spec_release.py @@ -6,6 +6,7 @@ import subprocess import tempfile import unittest +import zipfile ROOT = Path(__file__).resolve().parents[1] @@ -33,6 +34,19 @@ def test_two_clean_archive_builds_are_identical(self) -> None: hashlib.sha256(left.read_bytes()).digest(), hashlib.sha256(right.read_bytes()).digest(), ) + with zipfile.ZipFile(left) as archive: + prefix = f"iicp-spec-v{version}/" + names = set(archive.namelist()) + for required in ( + "LICENSE", + "GOVERNANCE.md", + "SECURITY.md", + "CONTRIBUTING.md", + "CONTINUATION.md", + "docs/governance/public-artifact-boundary.md", + "ecosystem/public-repositories.json", + ): + self.assertIn(prefix + required, names) if __name__ == "__main__": diff --git a/tools/test_standards_review_bundle.py b/tools/test_standards_review_bundle.py new file mode 100644 index 0000000..ceec388 --- /dev/null +++ b/tools/test_standards_review_bundle.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import hashlib +import json +from pathlib import Path +import subprocess +import tempfile +import unittest +import zipfile + + +ROOT = Path(__file__).resolve().parents[1] +SOURCE = ROOT / "standards/ietf/draft-roble-iicp-peer.md" + + +class StandardsReviewBundleTest(unittest.TestCase): + def test_bundle_is_deterministic_and_self_describing(self) -> None: + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + rendered = root / "rendered" + rendered.mkdir() + for suffix in ("xml", "txt", "html"): + (rendered / f"{SOURCE.stem}.{suffix}").write_text( + f"test {suffix}\n", encoding="utf-8" + ) + outputs = [root / "first", root / "second"] + for output in outputs: + subprocess.run( + [ + "python3", + str(ROOT / "tools/build_standards_review_bundle.py"), + "--rendered-dir", + str(rendered), + "--output-dir", + str(output), + ], + cwd=ROOT, + check=True, + capture_output=True, + text=True, + ) + + name = f"{SOURCE.stem}-review-bundle.zip" + left = outputs[0] / name + right = outputs[1] / name + self.assertEqual( + hashlib.sha256(left.read_bytes()).digest(), + hashlib.sha256(right.read_bytes()).digest(), + ) + + prefix = f"{SOURCE.stem}-review-bundle/" + with zipfile.ZipFile(left) as archive: + names = set(archive.namelist()) + for required in ( + "LICENSE", + "SECURITY.md", + "CONTINUATION.md", + "docs/governance/public-artifact-boundary.md", + "ecosystem/public-repositories.json", + "standards/REVIEWING.md", + "standards/ietf/evidence-matrix.md", + f"standards/ietf/{SOURCE.name}", + f"rendered/{SOURCE.stem}.xml", + f"rendered/{SOURCE.stem}.txt", + f"rendered/{SOURCE.stem}.html", + "SHA256SUMS.json", + ): + self.assertIn(prefix + required, names) + manifest = json.loads(archive.read(prefix + "SHA256SUMS.json")) + for relative, expected in manifest["files"].items(): + actual = hashlib.sha256(archive.read(prefix + relative)).hexdigest() + self.assertEqual(expected, actual, relative) + + +if __name__ == "__main__": + unittest.main()