spec: canonical-channel-access-v1 (PENDING) — one-system access architecture#79
spec: canonical-channel-access-v1 (PENDING) — one-system access architecture#79chitcommit wants to merge 6 commits into
Conversation
…cture
Canonical contract for how any channel acquires credentials to call a
ChittyOS service. Single broker (ChittyConnect), audience-scoped ephemeral
tokens, deprecates the shared CHITTY_AUTH_SERVICE_TOKEN pattern.
Implementation status (per §0.1):
- LIVE today on connect.chitty.cc (verified at chittyconnect/src/api/router.js:146-197,
auth header X-ChittyOS-API-Key):
/api/credentials/{provision,types,health,audit,revoke}
/api/v1/sessions/*, /api/auth/keys/*, /api/connections/*,
/api/v1/connect/*, /api/execute
- PROPOSED (tracked in chittyconnect#364, returns 404 today; do NOT consume):
/api/v1/tokens/mint, /api/v1/tokens/verify,
/api/v1/channels/register, /api/v1/channels/{id}/rotate-key
Issue closures (chittyconnect#231, chittyentity#343) are gated on §9.3 —
mint/verify routes verified live in production. References chittyentity#306
(parked tracking task).
Status: DRAFT. Owner: chittycanon://core/services/connect.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📝 WalkthroughWalkthroughThis PR introduces a new canonical specification document ( ChangesCanonical Channel Access Specification
🎯 4 (Complex) | ⏱️ ~60 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
There was a problem hiding this comment.
Pull request overview
Adds a DRAFT “canonical contract” spec that standardizes how all channel surfaces acquire credentials via ChittyConnect (broker-scoped keys → audience-scoped short-lived tokens), and documents the deprecation/migration away from the shared CHITTY_AUTH_SERVICE_TOKEN pattern.
Changes:
- Introduces a new canonical spec covering registration, token mint/verify, recovery routine, and operator-visibility gating.
- Documents the Tier 2+ migration pattern to minted-token verification (
verifyMintedToken/@chittyos/connect-verify). - Proposes a new compliance dimension (
channel-access-pattern) and its intended detection signal.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| This pattern is the root cause of the false-alarm issues | ||
| chittyconnect#231 / chittyentity#343. The shared token in 1Password vault | ||
| `ChittyOS/CHITTY_AUTH_SERVICE_TOKEN` (`ca1d75…`) does not match what is | ||
| deployed in the worker's `env.CHITTY_AUTH_SERVICE_TOKEN`. The drift is invisible |
| `@chittyos/connect-verify` is published by chittyconnect; offline JWT verify | ||
| with a 24h cache of ChittyConnect's signing key (KV: `connect:jwks`). One |
| 3. **Verify live**: `curl -fsS connect.chitty.cc/api/v1/tokens/mint` and | ||
| `/verify` return non-404 with documented shapes; record evidence in PR | ||
| body. This is the gate for §8 issue closure. |
| Add to `chittyops/compliance/checks.yml`: | ||
|
|
||
| ```yaml | ||
| channel-access-pattern: | ||
| description: | | ||
| Tier 2+ services must verify ChittyConnect-minted tokens (audience+scope), | ||
| NOT compare against a shared env.CHITTY_AUTH_SERVICE_TOKEN. | ||
| applies_to_tier: [2, 3, 4, 5] | ||
| signal: | ||
| - file: src/auth.ts (or equivalent) | ||
| - must_contain: "verifyMintedToken" OR "connect-verify" | ||
| # The live deprecated pattern in chittyagent-tasks/src/auth.ts:7 is | ||
| # h.slice(7) !== c.env.CHITTY_AUTH_SERVICE_TOKEN | ||
| # so the signal must catch any reference to the shared env var, not just | ||
| # a single equality form. | ||
| - must_not_contain_regex: "c\\.env\\.CHITTY_AUTH_SERVICE_TOKEN|env\\.CHITTY_AUTH_SERVICE_TOKEN" | ||
| remediation_template: templates/migrate-to-minted-auth.md | ||
| ``` |
| | **Cloudflare Worker** | `wrangler deploy` post-hook, registers as `did:chitty:channel:worker-<name>-<env>` | Worker secret `CHITTYCONNECT_BROKER_KEY` (set by chittyops reusable deploy workflow) | | ||
| | **GitHub Actions** | Workflow `getchitty-creds` action runs registration if no cached channel_id | Repo secret `CHITTYCONNECT_API_KEY` | | ||
| | **Homelab node** | `chittymarket-sync-daemon.sh` on first boot | `~/.ops/channel-broker-key` (mode 600, written by registration response) | | ||
| | **ChatGPT cloud MCP** | Gateway-mediated registration via `ch1tty.com/mcp` (server-side policy + sync, per global CLAUDE.md Capability Registration §) | ChittyConnect-held; never exposed to the client | |
…8 #306 status §3: prepend note that recovery routine is valid once §0.1 proposed routes ship; legacy shared-token path applies until then (per §4). §8 chittyentity#306: update bullet to reflect emit already landed via legacy path (task_id dadb508b-0420-4d36-aa71-a09f5b3f1439, privileged/legalink). #306 stays open as the §4 migration anchor; closure ties to §9.3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses all 5 BLOCKERS and 5 NITS from the Cardinal audit of specs/canonical-channel-access-v1.md. Frontmatter (BLOCKER 1, NIT 7, NIT 10): - Add author, created (2026-06-04), modified (2026-06-10), certifier, contributors, category, tags, references[], related[] - Move footer signature into frontmatter + provenance block - Fix owner URI: chittycanon://core/services/connect -> chittycanon://core/services/chittyconnect (per CHARTER.md) Citations (BLOCKER 2, BLOCKER 5): - Add @canon header annotations for governance, charter, architecture - §0 links ChittyConnect CHARTER.md / CHITTY.md canonical URIs - §7 checks.yml fragment carries @canon citations to chittycanon://chittyos/registry/services and chittycanon://docs/ops/architecture/chittyconnect Terminology (NIT 8): - §0 introduces ChittyEntity (actor with agency, P-Synthetic) vs. channel (access surface, likely L) per chittycanon://gov/governance - §5 reworded: "ChittyEntity (via its channel)" not "channel/agent" Cross-references (NIT 6): - §9 split into §9.1 (library+endpoints), §9.2 (live verification), §9.3 (migration+closure). All §9.3 references retargeted to §9.2 (live verification is the actual closure gate). Open architectural questions (BLOCKER 3, BLOCKER 4, NIT 9): - New §10 surfaces the two architectural questions that cannot be resolved without operator decision: - Q1: did:chitty:channel:* vs canonical ChittyID format VV-G-LLL-SSSS-T-YM-C-X. Three options (A: DID-as-display-label, B: distinct identifier class, C: drop DID grammar). Recommended: Option A. - Q2: P/L/T/E/A classification of channel surfaces. Three options (A: branched type at registration, B: channels=L, ChittyEntities=P separately bound, C: all channels=P). Recommended: Option B. - §10.3 declares agent.chitty.cc/api/v1/channels/register registry status as "not yet registered" Spec remains DRAFT until §10 questions are resolved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…2 Option B Adjudicated 2026-06-10 by the dynamic three-wise-men panel (chittyclaw via Cloudflare AI Gateway). Both verdicts unanimous, no dissent. §10.1 — DID-vs-ChittyID: Option A (DID-as-display-label). The `did:chitty:channel:*` form is a human-readable alias only; the canonical ChittyID (VV-G-LLL-SSSS-T-YM-C-X) is minted alongside and is the authoritative identifier in storage, lookup, audit, and ledger. Respects chittycanon://gov/governance#identityRules.prohibition. §10.2 — P/L/T/E/A classification: Option B (heterogeneous per-surface typing). Cloudflare Workers / GH Actions runners → L (virtual). VM Claude Code / ChatGPT MCP → P (Synthetic). Homelab nodes → L (physical). Overrides the prior "recommended Option B (uniform L)" framing; uniform L flattened distinct semantics. Aligns with global CLAUDE.md "Claude contexts are Person (P), Synthetic — NEVER Thing". Changes: - §10.1 / §10.2: open-question blocks replaced with closed RULING blocks - §0 banner: "open questions" callout replaced with "rulings applied" - §0 terminology: channel type framing updated to heterogeneous - §1 mandate 1: registration response returns canonical chitty_id + display-label did; broker-scoped key unchanged - §6 wiring table: explicit Entity type column added per Option B - Frontmatter: decisions[] array added recording both panel adjudications; modified bumped (already 2026-06-10) - Provenance footer: ruling revision logged Status posture: remains DRAFT pending operator promotion review. All hygiene blockers (commit 743fcf9) and architectural blockers (this commit) are now closed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ator sign-off) Lifecycle transition authorized by operator on 2026-06-10. All prior gates closed: - Hygiene (5 blockers + 5 nits) — Code Cardinal audit, commit 743fcf9 - Architectural Q1 (§10.1 DID-vs-ChittyID) — panel ruling Option A, commit 67a63f9 - Architectural Q2 (§10.2 P/L/T/E/A typing) — panel ruling Option B, commit 67a63f9 Changes: - frontmatter: status DRAFT → PENDING - frontmatter: appended decisions[] entry lifecycle-2026-06-10-promotion - §0.1 banner: DRAFT → PENDING with promotion provenance - footer Provenance: added lifecycle line + revision entry certifier remains `pending` — flips to canonical authority at CERTIFIED stage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Canonical owner of certification lifecycle per CHITTYFOUNDATION/chittycertify/CHARTER.md. Distinct from ChittyCert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
specs/canonical-channel-access-v1.md (2)
256-256: ⚡ Quick winAdd language specifier to fenced code block.
The recovery routine steps should specify a language for proper rendering. Consider adding
textorplainas the language identifier.📝 Proposed fix
-``` +```text 1. Re-mint: POST /api/v1/tokens/mint with same audience+scope, fresh ttl. 2. If 401: POST /api/v1/channels/register with current host fingerprint.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@specs/canonical-channel-access-v1.md` at line 256, The fenced code block containing the recovery routine steps in specs/canonical-channel-access-v1.md lacks a language specifier; update that fenced block (the three-backtick code fence that lists "1. Re-mint..." and "2. If 401...") to include a language identifier such as "text" (e.g., replace ``` with ```text) so the recovery steps render correctly.Source: Linters/SAST tools
143-164: ⚡ Quick winAdd language specifier to fenced code block.
The ASCII diagram should specify a language for proper rendering and syntax highlighting. Consider adding
textorplainas the language identifier.📝 Proposed fix
-``` +```text ┌────────────┐ 1. register ┌──────────────────┐ │ Channel │ ─────────────▶ │ ChittyConnect │🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@specs/canonical-channel-access-v1.md` around lines 143 - 164, The ASCII diagram fenced code block that starts with "┌────────────┐ 1. register ┌──────────────────┐" is missing a language identifier; update the opening fence to include a language such as ```text (or ```plain) so the diagram renders with proper formatting and syntax highlighting, and ensure the closing ``` remains unchanged to match the fence.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@specs/canonical-channel-access-v1.md`:
- Around line 256-270: Step 6 is inconsistent: after the retry in step 5 fails
the same recovered token may not work to emit the agent_event; update the
procedure so that the agent_event `policy_blocked_channel_access` is either sent
to an alternate ingestion path that accepts the broker key (e.g., a
broker-authenticated endpoint) rather than the target that failed, or add a
guaranteed fallback when emit to chittyagent-tasks fails (e.g., enqueue to a
dead-letter queue, write a durable local log, or post to an operator-facing
alerting service); reference the event name
`agent_event`/`policy_blocked_channel_access`, the target service
`chittyagent-tasks ingest`, and the recovered token from step 5 when specifying
the alternative emission or fallback behavior.
- Around line 336-344: The table entry for "ChatGPT cloud MCP" currently
references "global CLAUDE.md Capability Registration §" with an incomplete
section marker; update that reference in the table to either include the exact
section identifier (e.g., "CLAUDE.md Capability Registration §3.2" or whatever
the correct section number/title is) or remove the trailing "§" and use a
general phrase like "CLAUDE.md Capability Registration" so the reference is
unambiguous; edit the table row containing "ChatGPT cloud MCP" / "global
CLAUDE.md Capability Registration §" to apply this change.
- Around line 307-326: The "active session" phrase in the
operator-visibility-gate check is ambiguous; update the spec and the
scripts/operator-visibility-gate.sh check to define "session" explicitly and
describe the lookup logic: state that a session is the operator's authenticated
channel lifecycle (start = channel open/auth token issuance, end = channel close
or token revoke), require a session_id correlated to ingest records, and mandate
the script look up ingest records where source_type=concierge_invocation AND
payload.concierge in ['chico','chittyconnect'] AND payload.session_id ==
current_session_id (fallback: if no session_id present, use a bounded timestamp
window derived from session_start to session_end), and document how session
boundaries are determined (channel open/close events or auth token timestamps)
so operator-visibility-gate.sh can reliably return exit 0 only when that scoped
invocation exists.
---
Nitpick comments:
In `@specs/canonical-channel-access-v1.md`:
- Line 256: The fenced code block containing the recovery routine steps in
specs/canonical-channel-access-v1.md lacks a language specifier; update that
fenced block (the three-backtick code fence that lists "1. Re-mint..." and "2.
If 401...") to include a language identifier such as "text" (e.g., replace ```
with ```text) so the recovery steps render correctly.
- Around line 143-164: The ASCII diagram fenced code block that starts with
"┌────────────┐ 1. register ┌──────────────────┐" is missing a language
identifier; update the opening fence to include a language such as ```text (or
```plain) so the diagram renders with proper formatting and syntax highlighting,
and ensure the closing ``` remains unchanged to match the fence.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1b0fbc1d-a9d4-4f78-850a-2569575a4007
📒 Files selected for processing (1)
specs/canonical-channel-access-v1.md
| ``` | ||
| 1. Re-mint: POST /api/v1/tokens/mint with same audience+scope, fresh ttl. | ||
| 2. If 401: POST /api/v1/channels/register with current host fingerprint. | ||
| (idempotent — returns existing channel_id if already known) | ||
| 3. If 401: Check broker key freshness: | ||
| GET /api/v1/channels/{channel_id} → if `key_expires_at` < now, | ||
| trigger key rotation: POST /api/v1/channels/{id}/rotate-key. | ||
| 4. If 401: POST chittyconnect-internal: report drift event | ||
| (target's deployed token ≠ canonical token in 1Password). | ||
| This is the ONLY path that may surface to operator. | ||
| 5. Retry target call once with new minted token. | ||
| 6. If still failing: emit `agent_event` of type `policy_blocked_channel_access` | ||
| to chittyagent-tasks ingest (using the recovered token from step 5) so the | ||
| gap shows up in the work surface, not in operator chat. | ||
| ``` |
There was a problem hiding this comment.
Logical inconsistency in recovery routine step 6.
Line 267-269 states: "If still failing: emit agent_event... to chittyagent-tasks ingest (using the recovered token from step 5)". However, the condition "If still failing" means the retry in step 5 failed, suggesting the token may not be valid for the target. If the target is chittyagent-tasks and the retry failed against that same target, using the same token to emit the policy-blocked event will likely fail as well.
Consider either:
- Clarifying that the policy-blocked event is emitted to a different endpoint that accepts the broker key directly, or
- Specifying a fallback mechanism (e.g., local logging, dead-letter queue) when even the event emission fails.
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 256-256: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/canonical-channel-access-v1.md` around lines 256 - 270, Step 6 is
inconsistent: after the retry in step 5 fails the same recovered token may not
work to emit the agent_event; update the procedure so that the agent_event
`policy_blocked_channel_access` is either sent to an alternate ingestion path
that accepts the broker key (e.g., a broker-authenticated endpoint) rather than
the target that failed, or add a guaranteed fallback when emit to
chittyagent-tasks fails (e.g., enqueue to a dead-letter queue, write a durable
local log, or post to an operator-facing alerting service); reference the event
name `agent_event`/`policy_blocked_channel_access`, the target service
`chittyagent-tasks ingest`, and the recovered token from step 5 when specifying
the alternative emission or fallback behavior.
| ## 5 · Operator-visibility gate (the goal's triple-verified gate, programmable) | ||
|
|
||
| A ChittyEntity (via its channel) may surface a credential/access blocker to the operator | ||
| **only when ALL of the following are true** (checked programmatically, not by | ||
| human discretion): | ||
|
|
||
| | Check | Programmable signal | | ||
| |-------|---------------------| | ||
| | Recovery routine §3 ran to completion | `recovery_routine_exhausted: true` event in tasks | | ||
| | All other blockers in scope cleared | `chittyops audit --service=<X>` exit 0 on every dimension except `channel-access-pattern` | | ||
| | All GH/Linear/Notion issues for relevant repos addressed | `gh issue list --state=open --label=blocker` empty AND `chittyagent-tasks` queue has no `priority>=8` items for the repo | | ||
| | All PR comments/conversations/conflicts cured | `gh pr list --search "review:required OR is:dirty"` empty | | ||
| | All branches reviewed; GH status clean | `gh pr checks` green on all open PRs for the repo | | ||
| | ChittyConnect + chico were invoked | An ingest record exists with `source_type=concierge_invocation, payload.concierge in ['chico','chittyconnect']` within the active session (no fixed time bound — fresh sessions must not auto-trip this gate) | | ||
|
|
||
| These are checked by a new `chittyops` script | ||
| `scripts/operator-visibility-gate.sh`, which returns exit 0 only if all six | ||
| pass. The Stop hook installed by the operator this session can call this | ||
| script and refuse to render any credential/access blocker text otherwise. | ||
|
|
There was a problem hiding this comment.
Clarify "active session" scope in the ChittyConnect invocation check.
Line 320 requires checking for a concierge invocation "within the active session (no fixed time bound — fresh sessions must not auto-trip this gate)". The term "active session" is ambiguous and could lead to implementation confusion.
Consider explicitly defining:
- What constitutes a "session" (e.g., operator login session, channel lifecycle, time-bounded window)
- How session boundaries are determined programmatically
- What the lookup mechanism should query (e.g., session ID, timestamp range, correlation ID)
🧰 Tools
🪛 LanguageTool
[style] ~310-~310: Consider removing “of” to be more concise
Context: ...ess blocker to the operator only when ALL of the following are true (checked programma...
(ALL_OF_THE)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/canonical-channel-access-v1.md` around lines 307 - 326, The "active
session" phrase in the operator-visibility-gate check is ambiguous; update the
spec and the scripts/operator-visibility-gate.sh check to define "session"
explicitly and describe the lookup logic: state that a session is the operator's
authenticated channel lifecycle (start = channel open/auth token issuance, end =
channel close or token revoke), require a session_id correlated to ingest
records, and mandate the script look up ingest records where
source_type=concierge_invocation AND payload.concierge in
['chico','chittyconnect'] AND payload.session_id == current_session_id
(fallback: if no session_id present, use a bounded timestamp window derived from
session_start to session_end), and document how session boundaries are
determined (channel open/close events or auth token timestamps) so
operator-visibility-gate.sh can reliably return exit 0 only when that scoped
invocation exists.
| | Surface | Entity type | Registration trigger | Where broker key lives | | ||
| |---------|-------------|----------------------|------------------------| | ||
| | **VM-resident Claude Code** | **P (Synthetic)** | `SessionStart` hook on first run, idempotent | `op://ChittyOS-Core/<host>-channel-broker/credential` (per-host item, auto-created on registration) | | ||
| | **Cloudflare Worker** | **L (Virtual)** | `wrangler deploy` post-hook | Worker secret `CHITTYCONNECT_BROKER_KEY` (set by chittyops reusable deploy workflow) | | ||
| | **GitHub Actions runner** | **L (Virtual)** | Workflow `getchitty-creds` action runs registration if no cached chitty_id | Repo secret `CHITTYCONNECT_API_KEY` | | ||
| | **Homelab node** | **L (Physical)** | `chittymarket-sync-daemon.sh` on first boot | `~/.ops/channel-broker-key` (mode 600, written by registration response) | | ||
| | **ChatGPT cloud MCP** | **P (Synthetic)** | Gateway-mediated registration via `ch1tty.com/mcp` (server-side policy + sync, per global CLAUDE.md Capability Registration §) | ChittyConnect-held; never exposed to the client | | ||
| | **Mobile** | **L (Virtual)** acting on behalf of a **P** | OAuth flow returns chitty_id + broker key (slim-MCP `search` + `execute`) | Provider's secure keystore | | ||
| | **Future channels** | classified at registration | Register → Receive → Sync → Report → Enforce (per Channel Registration Protocol) | Channel-specific; broker-only key | |
There was a problem hiding this comment.
Complete section reference for CLAUDE.md.
Line 342 references "global CLAUDE.md Capability Registration §" with an incomplete section marker. Please specify the exact section number or remove the "§" symbol if referring to the document generally.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@specs/canonical-channel-access-v1.md` around lines 336 - 344, The table entry
for "ChatGPT cloud MCP" currently references "global CLAUDE.md Capability
Registration §" with an incomplete section marker; update that reference in the
table to either include the exact section identifier (e.g., "CLAUDE.md
Capability Registration §3.2" or whatever the correct section number/title is)
or remove the trailing "§" and use a general phrase like "CLAUDE.md Capability
Registration" so the reference is unambiguous; edit the table row containing
"ChatGPT cloud MCP" / "global CLAUDE.md Capability Registration §" to apply this
change.
Status: PROMOTED TO PENDING 2026-06-10 by operator sign-off
Lifecycle: DRAFT (2026-06-04) → PENDING (2026-06-10) → CERTIFIED (TBD)
Promotion chain (commits in order):
PENDING posture: spec is open for certifier review. Frontmatter
certifierremainspending— flips to canonical authority (chittycanon://gov/authority/chittygovor domain owner) at CERTIFIED stage. Do not merge until certifier signs.Summary
Canonical contract for how every channel (VM Claude Code, Workers, mobile, ChatGPT cloud MCP, homelab, future models) acquires credentials — single broker (ChittyConnect), audience-scoped ephemeral tokens, deprecates the shared
CHITTY_AUTH_SERVICE_TOKENpattern.✅ Architectural rulings (resolved 2026-06-10)
Both prior open questions adjudicated by the three-wise-men dynamic panel (chittyclaw via Cloudflare AI Gateway). Both verdicts unanimous, no dissent. Applied in commit 67a63f9.
§10.1 — DID-vs-ChittyID → Option A (DID-as-display-label)
VV-G-LLL-SSSS-T-YM-C-X) is authoritative in storage, lookup, audit, and ledger.did:chitty:channel:<host>-<surface>-<n>is retained as a human-readable alias only.chittycanon://gov/governance#identityRules.prohibition; no new canonical identifier class.§10.2 — P/L/T/E/A classification → Option B (heterogeneous per-surface typing)
Cardinal remediation (commit 743fcf9)
Resolves all 5 hygiene blockers and 5 nits from the ChittyCanon Code Cardinal audit. See commit message for full detail.
Implementation status (§0.1)
Live on connect.chitty.cc — verified at chittyconnect/src/api/router.js:146-197, auth header X-ChittyOS-API-Key:
Proposed — tracked in chittyconnect#364, returns 404 today; do NOT consume:
Issue closure (gated)
Per §8/§9.2, chittyconnect#231 and chittyentity#343 close only after §9.2 verifies mint/verify routes live in production. References chittyentity#306 (parked).
Companion PR
chittyentity#372 — corrects stale host + vault in INGESTION.md, marks shared-token Authorization line DEPRECATED inline.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit