Skip to content

Chore/backlog sweep 2026 07 - #66

Merged
macanderson merged 5 commits into
mainfrom
chore/backlog-sweep-2026-07
Jul 29, 2026
Merged

Chore/backlog sweep 2026 07#66
macanderson merged 5 commits into
mainfrom
chore/backlog-sweep-2026-07

Conversation

@macanderson

@macanderson macanderson commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Pull request

Summary

What changed

Checklist

  • One logical change per PR (smaller lands faster)
  • Gate is green locally — fmt, clippy -D warnings, test
  • A witness test is included, or a reason there isn't one is stated below
  • Docs updated in the same PR if behavior or flags changed (README.md,
    docs/, doc comments, --help text)
  • All commits signed off (git commit -s, DCO)
  • CHANGELOG.md updated under [Unreleased] if user-visible

Protocol-stability impact (if a spec/wire change)

  • Not applicable — no wire or spec change
  • Additive (new optional field/check) — safe within contextgraph/1
  • Wire-breaking — requires contextgraph/2; explain below

License

By submitting this pull request, I agree to dual-license this contribution
under MIT OR Apache-2.0, as certified by my DCO sign-off.

Summary by Sourcery

Enforce and document stricter protocol and transport guarantees around HTTP credentials and error codes, introduce a conformance registry and downstream canary tooling ahead of the 1.0 freeze, and add automated, gated publishing workflows for crates and SDKs.

New Features:

  • Add bearer credential support for HTTP providers with redacted rendering and explicit Unauthorized handling, plus loopback-only plaintext allowance and refusal of insecure non-loopback transports.
  • Introduce a conformance registry and badge for providers, including initial entry for the bundled example provider and guidance on how to get listed.
  • Add explicit error codes for unsupported representations and incompatible protocol versions, wiring them through host errors so callers can react structurally.
  • Extend the protocol spec with usage-reporting requirements and a deferred sketch for multi-hop graph traversal, and align documentation around these semantics.
  • Expose a host API for adding HTTP providers with optional credentials and re-export the new Credential type.

Enhancements:

  • Tighten malformed-input conformance checks to require a structured bad_request code rather than accepting arbitrary errors, with new fixture behavior and tests.
  • Preserve provider error codes through HostError so hosts can distinguish structured provider failures instead of relying on free-form messages.
  • Clarify schema $id hosting and validation strategy to point at a resolvable GitHub-raw URL while keeping the site mirror byte-identical as future hosting is wired.
  • Document and partially automate downstream canary builds for stella and (future) oxagen to detect breaking changes against external consumers before releases.
  • Clarify host reactions and retry semantics for new and existing ErrorCode variants, including permanent drop behavior for incompatible version handshakes.

Build:

  • Add a crates.io dry-run CI job to ensure contextgraph-types still packages cleanly for publishing.
  • Introduce a tag-triggered Release workflow that publishes crates to crates.io in dependency order, waiting for index propagation between steps.
  • Add a guarded publish-sdks workflow and detailed SDK publishing guide covering npm, PyPI, and Go module release flows and safety constraints.
  • Add helper scripts for waiting on crate index propagation and for running downstream canary builds of stella against a local CGP checkout.

CI:

  • Add downstream-canary workflow to build and test stella (and stub out oxagen) against this repository’s HEAD on schedule and relevant PRs, reporting failures as advisory warnings.
  • Wire SDK and crate publish workflows to GitHub Environments and secrets so that publishing is gated on manual approval and presence of credentials, never happening on tag push alone.

Documentation:

  • Document the conformance registry, submission process, and usage of the static conformant badge in both Rust and site docs.
  • Update SPEC and protocol-surface docs with usage-report (UR1) semantics, clarify HTTP transport rules C7/C8 conformance status, and describe deferral of multi-hop traversal.
  • Expand provider implementation docs with guidance on getting listed in the registry and clarify adaptive-context reconciliation and downstream canary behavior.
  • Add publishing guidance for the Rust crates and each SDK, including CI-driven release paths, environment setup, and one-way-door caveats.
  • Add crates.io and docs.rs badges to root and per-crate READMEs, and clarify SDK README status for not-yet-published Python and Go packages.

Tests:

  • Add unit tests for HTTP transport security and credential handling, including loopback plaintext allowance, non-loopback refusal, bearer header attachment, and redacted credential rendering.
  • Strengthen conformance tests for malformed input handling, including a mislabelled-malformed case to ensure only bad_request is accepted for malformed lines.

Chores:

  • Add a static conformant SVG badge and a captured conformance report asset under the site’s public tree for use by the registry and external READMEs.
  • Adjust various call sites to the updated Host::add_http / HttpProvider APIs and error shapes to accommodate credentials and structured error codes.

…ma $id

Five file-disjoint backlog issues, all additive (no wire/Rust-logic change):

- #20 Conformance registry page + reproducible-report seed + badge + PR
  submission checklist. Seed report is a verified 12/12 capture of
  `contextgraph-inspect stdio --json` against the bundled example provider.
- #16 Tag-triggered, environment-gated crates.io release.yml + a credential-free
  `publish-dry-run` CI job + crates.io/docs.rs badges. Version cut and the
  crates-io environment/secret remain the owner's decision.
- #59 sdk/PUBLISHING.md + tag-gated publish-sdks.yml; PyPI/Go publishes and the
  Go tag remain human-only. npm already live via #46.
- #29 downstream-canary.yml builds stella's contextgraph-* consumers against
  HEAD (advisory); oxagen-canary activates once OXAGEN_PLATFORM_TOKEN is wired.
- #58 schema $id repointed to the GitHub-raw URL that resolves today (interim
  until #57's Vercel relink); schema validate-examples.py green, mirror
  byte-identical.

Closes #20, #29, #58
Refs #16, #59 (publish/tag/secret steps are human-only)

Claude-Session: https://claude.ai/code/session_01Co9faUWdYC1SPqrof7njyD
…mment (#49)

Closes the two remaining #49 "survivors":

- SPEC.md gains a normative §7.3 "Usage reports" (UR1): a host MUST be able to
  produce a usage report whose budget_consumed equals the summed token_cost of
  served frames, referencing them by FrameId — backed by the existing, tested
  contextgraph-host::FanOut::usage_report. Resolves the "U1" anchor collision
  with §13's ignore-unknown-members rule by labelling this UR1 across SPEC.md,
  docs/context-reuse.md, and docs/protocol-surface.md, and repointing §14's A1
  cross-reference at §7.3.
- Reword the schema canonical_token_cost $comment so tokenizer_ref pairs only
  with canonical_token_cost (the exact-count companion), never the byte-formula
  token_cost (§B3/§7.2) — resolving #50's tokenizer residual. Source and site
  schema copies stay byte-identical.

schema/validate-examples.py green.

Closes #49
Refs #50

Claude-Session: https://claude.ai/code/session_01Co9faUWdYC1SPqrof7njyD
The graph itself is already real and witnessed — §8 specifies graph frames, the
open `rel` vocabulary, and the G1/G2/G3/G4 checks (G4's anchored predicate and
its `anchor-relevance` check landed in #63/#64). The one remaining #7 acceptance
box was the design sketch for multi-hop traversal.

Adds docs/sketches/context-neighbors.md (a `context/neighbors { uri, rels, depth }`
envelope pair as a post-1.0 additive minor, defined so `depth: 1` ≡ the G4
anchored set) following the docs/sketches/resolve.md template, and a §8.3
forward-reference in SPEC.md mirroring the §6.4.1 deferral pattern. No wire
change — traversal beyond one hop is explicitly out of scope for the 1.0 freeze.

Closes #7

Claude-Session: https://claude.ai/code/session_01Co9faUWdYC1SPqrof7njyD
#9)

The wire already carried `code: Option<ErrorCode>`; nothing read it. This plumbs
it end to end and tightens the conformance floor:

- ErrorCode gains `unsupported_representation` (§P5) and `incompatible_version`
  (§H3), wired through as_str/From<&str>/reaction(). incompatible_version is
  permanent — a new HostReaction::DropProvider (the request is fine, the provider
  is unusable; distinct from DoNotRetry/Respawn/ReportAndCount).
- HostError::Provider now carries `code`; the four http.rs/stdio.rs error arms
  pass it through instead of discarding it, so FanOut::failures() surfaces it.
- The malformed-input-tolerance conformance check now passes only on a
  `bad_request` code (was: any Envelope::Error), per SPEC.md R1. A new
  `--misbehave mislabel-malformed` mode (answers `internal`) exercises the
  tightened check in conformance-red.sh, with a matching suite test.

Gate green: fmt, clippy -D warnings, test --workspace, conformance-green (12/12),
conformance-red (all misbehave modes caught).

Closes #9

Claude-Session: https://claude.ai/code/session_01Co9faUWdYC1SPqrof7njyD
C7/C8 were specified (§4.2) but listed as a live enforcement gap (§11.1). This
implements them in the reference host:

- C7 (TLS for non-loopback): HttpProvider refuses a plaintext http:// target to
  any non-loopback host with HostError::InsecureTransport, BEFORE the client is
  built or DNS resolves. Loopback (localhost / 127.0.0.0/8 / [::1]) stays exempt
  so the wiremock suite keeps working.
- C8 (credentials never logged): a new Credential type whose Debug AND Display
  both render only "Credential(<redacted>)" (secret reachable only via a
  crate-private expose()); attached via reqwest bearer_auth, never a format
  string. A redaction test asserts no HostError/format string leaks the secret.
- connect_with_auth / Host::add_http take an optional Credential (connect stays
  as a back-compat None wrapper); a 401 surfaces as HostError::Unauthorized.
- SPEC.md §11.1 updated: C7/C8 now enforced + unit-tested at the
  transport-refusal/redaction level; full live-TLS-peer conformance remains the
  stated next increment (unchanged).

Gate green: fmt, clippy -D warnings, test (119 host + 4 new), conformance
green/red, schema validate. wiremock was already a dev-dep.

Closes #13

Claude-Session: https://claude.ai/code/session_01Co9faUWdYC1SPqrof7njyD

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @macanderson, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@sourcery-ai

sourcery-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements HTTP transport hardening and credential redaction in the host, wires through structured error codes, and adds CI + documentation scaffolding for publishing crates/SDKs and tracking conformant providers and downstream consumers ahead of the protocol freeze.

File-Level Changes

Change Details Files
Harden HTTP provider transport by enforcing TLS for non-loopback hosts and supporting optional bearer credentials with full redaction guarantees.
  • Introduce a Credential wrapper type whose Debug/Display render as a fixed redacted placeholder and are only exposable via a crate-private method for header attachment.
  • Add loopback host detection and a refuse_insecure_transport guard that rejects plaintext http:// URLs to non-loopback hosts with a new HostError::InsecureTransport before any network I/O.
  • Extend HttpProvider to carry an optional Credential, add a connect_with_auth constructor, and ensure every HTTP exchange (handshake, query, verify, shutdown) attaches the bearer token via reqwest::RequestBuilder::bearer_auth when present.
  • Update post_envelope to take an optional Credential, attach Authorization headers, and translate HTTP 401 into a typed HostError::Unauthorized; propagate provider error codes through HostError::Provider.
  • Add targeted unit tests verifying C7/C8 semantics: refusing non-loopback plaintext, allowing loopback, attaching Authorization correctly, and ensuring credentials never appear in debug output or surfaced HostError strings.
contextgraph-host/src/http.rs
contextgraph-host/src/error.rs
contextgraph-host/src/host.rs
contextgraph-host/src/stdio.rs
Tighten conformance behavior and error semantics, especially around malformed input handling and structured ErrorCode mapping.
  • Refine the malformed-input-tolerance conformance check to require a bad_request ErrorCode (not just any error) when a provider rejects malformed input, and treat other codes as failures.
  • Add new ErrorCode variants (UnsupportedRepresentation, IncompatibleVersion) and map them to appropriate HostReaction values, including a new DropProvider reaction for permanent incompatibility.
  • Update ErrorCode tests to cover new variants and non-retryability semantics, and ensure they serialize/deserialize correctly.
  • Extend conformance fixtures to support a MislabelMalformed misbehavior mode and add a test that such providers fail malformed-input-tolerance while still passing handshake.
contextgraph-conformance/src/lib.rs
contextgraph-conformance/src/bin/contextgraph-example-docs.rs
contextgraph-conformance/tests/conformance_suite.rs
contextgraph-types/src/error_code.rs
Introduce a conformance registry and guidance for getting providers listed, including a static badge asset and corresponding site/docs wiring.
  • Add docs/registry.md and site/content/docs/registry.mdx describing the registry, listing the bundled contextgraph-example-docs provider with a captured JSON report, and documenting the submission process and badge usage.
  • Add a static conformant.svg badge and publish the captured example-docs conformance report under site/public/registry.
  • Link the registry from the main docs index pages and extend provider-implementation docs with a "Getting listed once you're green" section and badge instructions.
  • Update the PR template with a Registry submission checklist requiring an exact, reproducible contextgraph-inspect --json invocation and all-pass report before adding rows.
docs/registry.md
site/content/docs/registry.mdx
site/public/badges/conformant.svg
site/public/registry/contextgraph-example-docs.report.json
docs/implementing-a-provider.md
site/content/docs/implementing-a-provider.mdx
.github/PULL_REQUEST_TEMPLATE.md
docs/index.md
site/content/docs/index.mdx
Document and automate crate and SDK publishing, including a tag-triggered crates.io release workflow, SDK registry workflows, and dry-run CI.
  • Add PUBLISHING.md guidance for using a tag-triggered GitHub Actions Release workflow that publishes contextgraph-types -> contextgraph-host -> contextgraph-conformance in dependency order, including a wait-for-crate sparse-index poller script.
  • Add sdk/PUBLISHING.md documenting npm, PyPI, and Go module release procedures, one-way-door constraints, and post-publish verification steps; clarify that TypeScript is already published while Python/Go are not.
  • Introduce publish-sdks.yml that separates credential-free verify-* jobs (build + conformance) from manual, environment-gated publish-* jobs for npm and PyPI, ensuring tag pushes alone cannot publish and refusing to run without required secrets.
  • Add a publish-dry-run job to CI that runs cargo publish --dry-run -p contextgraph-types on every PR as a cheap packaging sanity check.
  • Update SDK and crate README files with crates.io/docs.rs badges and "not yet published" notes where applicable, and clarify manual vs workflow-driven tag ordering in PUBLISHING docs.
PUBLISHING.md
sdk/PUBLISHING.md
.github/workflows/release.yml
.github/workflows/publish-sdks.yml
.github/workflows/ci.yml
.github/scripts/wait-for-crate.sh
README.md
contextgraph-types/README.md
contextgraph-host/README.md
contextgraph-conformance/README.md
sdk/README.md
sdk/python/README.md
sdk/go/README.md
Clarify and extend SPEC and surrounding docs regarding usage reports, traversal deferral, HTTP transport guarantees, attribution, and downstream canary CI.
  • Add SPEC §7.3 describing usage reports and define UR1, and update references in context-reuse.md and protocol-surface.md from U1 to UR1.
  • Add SPEC §8.3 explicitly deferring multi-hop traversal to a post-1.0 additive minor, and introduce docs/sketches/context-neighbors.md with a concrete design sketch consistent with G4 anchoring.
  • Update SPEC §10 verification section to record that C7 (TLS for non-loopback) and C8 (credential non-logging) are now enforced and unit-tested, while live TLS-peer conformance remains future work; also clarify bad_request expectations for malformed input handling.
  • Adjust attribution requirement A1 in SPEC to reference usage reports §7.3 and add explanatory notes in adaptive-context-reconciliation docs and ADR 0007 about the new downstream-canary workflow.
  • Introduce schema/validate-examples.py commentary and behavior for an interim $id pointing at the GitHub raw schema URL, while keeping a byte-identical copy under site/public/schema for future domain hosting fixes.
SPEC.md
docs/context-reuse.md
docs/protocol-surface.md
docs/adaptive-context-reconciliation.md
docs/adr/0007-protocol-product-boundary.md
docs/sketches/context-neighbors.md
schema/validate-examples.py
Add downstream canary CI to detect breaking changes in known consumers, with stella wired today and oxagen reserved for future integration.
  • Add downstream-canary.yml workflow that periodically and on relevant PRs builds stella against this repo’s HEAD via a local Cargo [patch], treating failures as advisory warnings and summarizing them in the job output.
  • Provide .github/scripts/downstream-canary-stella.sh to auto-discover contextgraph-* crates in this repo, patch stella’s Cargo.toml accordingly, identify dependent stella crates, and run cargo build/test on them.
  • Stub an oxagen-canary job that will check private oxagen-platform fixtures once a cross-org token is configured, currently emitting a notice when the token is absent and asserting fixture layout when present.
.github/workflows/downstream-canary.yml
.github/scripts/downstream-canary-stella.sh
docs/adaptive-context-reconciliation.md
docs/adr/0007-protocol-product-boundary.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@macanderson
macanderson merged commit eeba49c into main Jul 29, 2026
14 checks passed
@macanderson
macanderson deleted the chore/backlog-sweep-2026-07 branch July 29, 2026 23:49
macanderson added a commit that referenced this pull request Jul 30, 2026
Resolves the conflicts on PR #69. Most of this branch had already landed on
main via #66 and #67, so the merge is mainly about keeping what is genuinely
new (#28, #21, #2) and taking main's side everywhere #68 made a decision.

Resolution rules applied:

- site/ is retired (ADR 0008, #68). All nine modify/delete conflicts under
  site/ take main's deletion; the branch's edits to the .mdx mirrors and to
  site/public/schema/ are dropped rather than resurrected. tests/
  docs_site_witness_test.py goes with it — it asserted the site mirrored the
  markdown docs.
- Advertised artifact URLs take main's rewrite: cgp.oxagen.sh/badges/... and
  site/public/... become the GitHub-raw paths that check-deploy-hygiene.py
  enforces. This covers the three SDK READMEs, docs/registry.md,
  docs/implementing-a-provider.md and the CHANGELOG entry for #20.
- The CGP abbreviation convention (#21) is kept where it does not collide with
  the above: docs/index.md, docs/composition-walkthrough.md, and the
  "CGP maintainers" cell in the registry table now sit on top of main's paths.
- .github/workflows/ci.yml: the branch's publish-dry-run job is dropped
  because main already carries it (via #66) — keeping both would have created
  a duplicate YAML job key. The branch's `site: docs site builds` job is
  dropped for the same reason site/ is; main's deploy-hygiene job stands.
- schema/validate-examples.py keeps the new lifecycle-record section (#28) —
  13 fixtures plus the detached attestation — with its site/public/schema/
  mirror checks removed, since there is no second copy to keep in sync.
- docs/profiles/context-exchange-provider.md LF2 is restated: the normative
  MUST was a byte-identical site/public/schema/ mirror enforced by a check
  that no longer exists. It now pins the $id to GitHub-raw per ADR 0008. This
  was in cleanly auto-merged text, so git did not flag it.

Net contribution over main after the merge is 34 files / +2,507: the Context
Exchange Provider lifecycle profile (#28), the CGP abbreviation pass (#21),
and the README CI badge (#2 partial).

Verified: cargo fmt --check, cargo test --workspace --all-features,
cargo clippy -D warnings, python3 schema/validate-examples.py (all examples
validate), python3 .github/scripts/check-deploy-hygiene.py (deploy hygiene
holds), and all relative links in 58 markdown files resolve.

Claude-Session: https://claude.ai/code/session_014H5SE4vnAP4Nw1MBMHfUpt
macanderson added a commit that referenced this pull request Jul 30, 2026
Resolves the conflicts on PR #69. Most of this branch had already landed on
main via #66 and #67, so the merge is mainly about keeping what is genuinely
new (#28, #21, #2) and taking main's side everywhere #68 made a decision.

Resolution rules applied:

- site/ is retired (ADR 0008, #68). All nine modify/delete conflicts under
  site/ take main's deletion; the branch's edits to the .mdx mirrors and to
  site/public/schema/ are dropped rather than resurrected. tests/
  docs_site_witness_test.py goes with it — it asserted the site mirrored the
  markdown docs.
- Advertised artifact URLs take main's rewrite: cgp.oxagen.sh/badges/... and
  site/public/... become the GitHub-raw paths that check-deploy-hygiene.py
  enforces. This covers the three SDK READMEs, docs/registry.md,
  docs/implementing-a-provider.md and the CHANGELOG entry for #20.
- The CGP abbreviation convention (#21) is kept where it does not collide with
  the above: docs/index.md, docs/composition-walkthrough.md, and the
  "CGP maintainers" cell in the registry table now sit on top of main's paths.
- .github/workflows/ci.yml: the branch's publish-dry-run job is dropped
  because main already carries it (via #66) — keeping both would have created
  a duplicate YAML job key. The branch's `site: docs site builds` job is
  dropped for the same reason site/ is; main's deploy-hygiene job stands.
- schema/validate-examples.py keeps the new lifecycle-record section (#28) —
  13 fixtures plus the detached attestation — with its site/public/schema/
  mirror checks removed, since there is no second copy to keep in sync.
- docs/profiles/context-exchange-provider.md LF2 is restated: the normative
  MUST was a byte-identical site/public/schema/ mirror enforced by a check
  that no longer exists. It now pins the $id to GitHub-raw per ADR 0008. This
  was in cleanly auto-merged text, so git did not flag it.

Net contribution over main after the merge is 34 files / +2,507: the Context
Exchange Provider lifecycle profile (#28), the CGP abbreviation pass (#21),
and the README CI badge (#2 partial).

Verified: cargo fmt --check, cargo test --workspace --all-features,
cargo clippy -D warnings, python3 schema/validate-examples.py (all examples
validate), python3 .github/scripts/check-deploy-hygiene.py (deploy hygiene
holds), and all relative links in 58 markdown files resolve.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant