Skip to content

Keep Claude Code's new OTel event fields in both collector profiles; deny the rtk spelling of the skills CLI - #1238

Draft
seathatflowsinourveins wants to merge 2 commits into
mainfrom
fix/owed-checks-2.1.302
Draft

seathatflowsinourveins wants to merge 2 commits into
mainfrom
fix/owed-checks-2.1.302

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator

Scope

  • What this PR changes, in one or two sentences: Both collector profiles now keep the five event fields Claude Code added in 2.1.300 to 2.1.302, shape-guard them and keep them off SDK receipts. Before this, transform/privacy dropped them. The Claude settings template now also denies the rtk npx spelling of each of its 19 npx *skills deny rules. Only repository templates, profiles, tests and records change; no host configuration, hook, permission or service was touched.
  • Base commit: 90471d63f20918efa3a63ef949caffd8c012656c
  • Lane: lane:foundation
  • Owned paths touched: observability/collector/collector.yaml, observability/collector/README.md, evidence/artifacts/new-wsl-install-plan-20261002/config/otel.yaml, adoption/templates/claude.settings.template.json, tests/test_observability_tool_names.py, tests/test_install_claude_profile.py, tests/fixtures/install_plan_default_ports.json, docs/decisions/2026-10-02-new-wsl-client-configuration.md (a dated addendum only), and manifests/evidence.json (rows written by scripts/host_receipts.register_file).

This applies two findings of the command center's reviewed owed-checks report for Claude Code 2.1.302 (OWED-CHECKS-2.1.302-20261017.md): F5.1 (otel-fields, a defect) and F3.2 (rtk-hook, a gap). It uses only the report's diffs marked "main", applied byte for byte at its base, which is still origin/main. Each git apply --check exited 0. Every changed file's sha256 equals the report's post-change table. manifests/evidence.json equals the report's proposed manifest (7bfa6f74…) except for the one row of the record that commit 2 adds. The commits are one per finding: 6acd972c (otel-fields) and 6bf2eb5c (rtk-hook).

Two changes go beyond the report's diffs. The tests this PR had to run required both:

  1. tests/fixtures/install_plan_default_ports.json pins the default-host render of the 2604 otel.yaml. HostPortTests.test_default_host_renders_the_baseline_config_bytes failed after the profile change. The otel.yaml entry moves to the new render digest and keeps superseded_sha256 and superseded_reason, as the fixture's promptfoo-gateway.cjs entry already does. A script proved that the new render differs from the superseded one only in this PR's three source change blocks, and that none of the changed lines holds a port placeholder.
  2. The 19 new deny pieces raise the client-config counts, which RecordTests.test_the_counts_that_the_record_states_are_the_ones_check_prints reads from the record's latest projection. A dated ## Addendum 2026-10-17 gives the new projection (423 pieces, 383 wired, 172 through a slot), in the same form as that record's earlier addenda. The pieces are wired through the command-output slot by the existing claude/settings/permission/deny/Bash(rtk * map entry (adoption/new-wsl/client-config-map.json:265-275). The record's sha256 is pinned only by its own manifest row.

SOTA sources

  • Claude Code, anthropics/claude-code CHANGELOG.md at tag v2.1.302 (commit c017428c8c27e604840435048d5bce6a9a22c040, blob 490ea6ecb19b10ed612846d1e1269a4c9998db8a):
    • L126 (2.1.300): cache_creation_5m_tokens and cache_creation_1h_tokens on api_request.
    • L75 (2.1.301): classifier_verdict and permission_mode on tool_decision.
    • L76 (2.1.301): classifier_category on tool_decision when OTEL_LOG_TOOL_DETAILS=1.
    • L18 (2.1.302): the fix that sends classifier_category for most classifier blocks.
    • L130 (2.1.300): GenAI span attributes. They need no allowlist entry, because the templates export no Claude traces.
    • L916 (2.1.290): permission rules apply to the input a PreToolUse hook rewrote.
  • OpenTelemetry Collector: both profiles' distribution is otelcol-contrib 0.162.0 (evidence/artifacts/new-wsl-install-plan-20261002/install.sh:739, observability/collector/README.md:3-4), and the installed binary prints otelcol-contrib version 0.162.0. The component is the transform processor, open-telemetry/opentelemetry-collector-contrib v0.162.0 (tag object 0cea0d4f24220e2e54bf89b6ace0416cf6fdd593) processor/transformprocessor. Its OTTL functions in pkg/ottl/ottlfuncs/README.md at that tag: delete_key (L140), delete_matching_keys (L157), keep_keys (L321), set (L473), IsInt (L1415) and IsMatch (L1465).
  • rtk, rtk-ai/rtk tag v0.51.0 (commit e001f773f80b22b7dc4c7a79521b30e35aaef026; rtk --version on the host prints 0.51.0):

Evidence-class table

Claim Evidence class Command / receipt
Both profiles dropped the five fields at the base, and keep, guard and keep them off receipts after the fix synthetic NewClaudeEventFieldTests: FAILED (failures=2) with only the test applied at the base, OK after the fix
The 2604 profile, rendered for the default host, is a valid configuration on the pinned collector local_integration otelcol-contrib validate (0.162.0) on the base and head renders: exit 0 and 0. A negative control with IsMatchX in a new guard: exit 1, undefined function
The committed logs pipeline still keeps names and drops command text on the real collector local_integration OTELCOL_TEST_BIN=<installed 0.162.0> python3 -m unittest tests.test_observability_tool_names: 13 tests OK, NativeCollectorTests included
Every npx *skills deny has an rtk npx twin, the blocked commands are denied in both rtk spellings, and find/init stay allowed synthetic RtkSpellingSkillsCliDenyTests: FAILED (failures=39) with only the test applied, OK after the template fix
rtk rewrites npx, and Claude Code applies deny rules to the rewritten input source_review rtk v0.51.0 and [email protected] lines above. No probe through the installed rtk or the 2.1.302 binary was run
The new fields arrive with the stated types, and the host keeps them unrun Host steps below. The live collector and the host settings were not changed

Local commands run

$ git apply --check <each of the report's six main file diffs>   # the manifest diff was applied by register_file instead
exit 0 (each)

# otel-fields, fail first: only tests/test_observability_tool_names.py applied at 90471d63
$ python3 -m unittest -v tests.test_observability_tool_names.NewClaudeEventFieldTests
exit 1: FAILED (failures=2), one per profile ('cache_creation_5m_tokens' not found in the keep_keys list)
# after collector.yaml, the 2604 otel.yaml and the README
$ python3 -m unittest -v tests.test_observability_tool_names.NewClaudeEventFieldTests
exit 0: Ran 1 test, OK

# rtk-hook, fail first: only tests/test_install_claude_profile.py applied on top of commit 1
$ python3 -m unittest -v tests.test_install_claude_profile.RtkSpellingSkillsCliDenyTests
exit 1: FAILED (failures=39) (19 twin= and 20 denied= subtests)
# after the template
$ python3 -m unittest -v tests.test_install_claude_profile.RtkSpellingSkillsCliDenyTests
exit 0: Ran 1 test, OK

$ python3 scripts/validate.py
exit 0: {"components": 71, "hashed_files": 12284, "profiles": 4, "receipts": 240, "status": "passed"}
$ python3 scripts/evidence_manifest.py --check
exit 0: {"files": 12284, "status": "passed"}
$ python3 tools/adoption/new_wsl_client_config.py --check
exit 0: pieces: 423; wired: 383; not wired: 24; authorization: 16
$ NS2604_OBSERVABILITY_DATA=<scratch> otelcol-contrib validate --config=<default-host render of the 2604 otel.yaml>
exit 0 (base render 4b103f0b…, head render cb0ea279…)
$ OTELCOL_TEST_BIN=<installed otelcol-contrib 0.162.0> python3 -m unittest -v tests.test_observability_tool_names
exit 0: Ran 13 tests, OK
# Each test module that names a changed file's basename (grep -rl over tests/, uncapped: 148 modules), plus the
# other two observability modules, run alone as `python3 -m unittest tests.<module>` at head 6bf2eb5c and at base 90471d63
150 modules: 133 exit 0. The other 17 fail at the head exactly as at the base (same failing tests, same status lines);
0 new failures. All 17 depend on this host: jsonschema not installed (8), /usr/bin/zstd missing (2), host
port-allocation state (1; it passes with an empty XDG_CONFIG_HOME), a relative import when run as tests.<module> (1),
a cross-device git clone (1), a cached upstream artifact (1), a local-pages assertion (1), a fixture module with no
tests (1), and the landscape harness over the runner's 1200 s cap (1).
$ git fetch origin && git merge-tree --write-tree origin/main HEAD
exit 0: bcbbd1fdc852ba4c2e49ab820e8b0e454140398d (origin/main still 90471d63, so it equals HEAD's tree)

Decision record

No new decision record. The proposal is the command center's reviewed owed-checks report (F5.1, F3.2). docs/decisions/2026-10-02-new-wsl-client-configuration.md gains only the dated addendum described above; its earlier projections stay as history.

Host evidence

No evidence/hosts/ changes and no platform-status change.

Follow-ups and verification boundaries

These are for the command center. None was done here, because this PR changes repository files only:

  • Host settings: run python3 tools/adoption/apply_claude_settings.py --dry-run, review it, then apply. This adds the 19 rtk npx twins. The report notes it also adds Agent(codex:codex-rescue), which the live deny list lacks.
  • Host collector: re-run the installer step at evidence/artifacts/new-wsl-install-plan-20261002/install.sh:748, then restart ns2604-otel-collector. The host otel.yaml digest equals the plan's .g4-source-digests.json entry for it (read 2026-10-17), so the step's known_plan_render check accepts it for republishing. After a session with a cache write and a tool decision, read the five keys back: expect intValue for the two counts, and record the observed classifier and mode values.
  • Sequencing with PR docs(claude-native-practice): bring the practice pages current to Claude Code 2.1.302 #1234 (open draft, head 450608c8, which now carries the report's F5.2 note): its observation-inference note and slot row say neither collector profile keeps these five fields yet. Whichever of the two lands second must bring that note to the landed state (report F5.2).
  • Not closed (report residual): rtk proxy <command> gets past every prefix-anchored deny rule, the push and reset rules included. The report leaves this to the command center to weigh against actual exposure.
  • Not re-pointed: 27 path:line locators into the template sit at or past line 129. Each was checked: every one is in a dated record or in evidence, is pinned to a commit, or already names other content at the base, so none tracks the file. The note on the Bash(rtk * map entry still mentions only the force-push rules, although the entry now also covers the npx twins. The map is unchanged.

Checklist

  • Both corrections have failing-before and passing-after regression evidence, and each cites its upstream source at a pin.
  • No new or changed GitHub Actions or workflows.
  • No secrets printed, logged or committed; no new required secret, paid hosting, subscription or billing surface.
  • Peer-owned untracked files and worktrees preserved; work done in a separate worktree, never the shared checkout.
  • Historical decision, receipt and evidence content preserved; the one record touched gains a dated addendum only.
  • Two normal commits on origin/main, with the configured no-reply identity.

🤖 Generated with Claude Code

transform/privacy ends every log record with a strict keep_keys allowlist,
and neither collector profile listed the five event fields Claude Code
added in 2.1.300 to 2.1.302, so the collector dropped them:

- cache_creation_5m_tokens and cache_creation_1h_tokens on api_request
  (anthropics/claude-code [email protected] L126, 2.1.300)
- classifier_verdict and permission_mode on tool_decision (L75, 2.1.301)
- classifier_category on tool_decision when OTEL_LOG_TOOL_DETAILS=1
  (L76, 2.1.301; L18, the 2.1.302 fix that sends it for most classifier
  blocks)

observability/collector/collector.yaml and the 2604 profile the host
renders (evidence/artifacts/new-wsl-install-plan-20261002/config/otel.yaml)
now allowlist the five keys and guard them before keep_keys: the counts
must be integers, and each name must be a short identifier or it becomes
"other". They also keep all five off SDK receipts, through
transform/sdk_receipt's numeric-usage deletion and transform/tool_names's
receipt-name deletion. The span attributes of L130 (2.1.300) need no
entry, because the Claude templates set OTEL_TRACES_EXPORTER=none.

NewClaudeEventFieldTests reads both profiles as text. It fails on the
base bytes (FAILED (failures=2), one per profile) and passes after the
fix. The collector README rows name the fields. Evidence rows were
registered with scripts/host_receipts.py register_file.

Not in the report: tests/fixtures/install_plan_default_ports.json pins
the default-host render of the 2604 otel.yaml, so
HostPortTests.test_default_host_renders_the_baseline_config_bytes failed
after the profile change. Its otel.yaml entry moves to the new render
digest and keeps the superseded digest and the reason. The new render
differs from the superseded one only in this commit's lines, and no
rendered port changes.

Applies F5.1 of the owed-checks report
~/horizon-build/command-center/claude-native/OWED-CHECKS-2.1.302-20261017.md
(base 90471d6).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
rtk 0.51.0 rewrites every npx command to `rtk npx`
(rtk-ai/[email protected] src/discover/rules.rs:120), and since 2.1.290 Claude
Code applies permission rules to the input a PreToolUse hook rewrote
(anthropics/claude-code [email protected] L916). rtk's own deny check
matches the raw segment without stripping a leading assignment
(src/hooks/permissions.rs:84-90), while its rewrite strips one and puts it
back (src/discover/registry.rs:64-74, :1635-1653). So
`X=1 npx skills add ...` reached Claude Code as `X=1 rtk npx skills add ...`,
and no deny rule matched that spelling. A model can also type the rtk
spelling itself. The push denies already have `rtk git push` twins for the
same reason.

adoption/templates/claude.settings.template.json now has an `rtk npx` twin
right after each of its 19 `npx *skills` deny rules.
RtkSpellingSkillsCliDenyTests checks every twin, 10 blocked commands in
two rtk spellings, and 5 allowed find and init commands in both
spellings. It fails on the base template (FAILED (failures=39): 19
missing twins and 20 blocked spellings) and passes after the fix. Evidence
rows were registered with scripts/host_receipts.py register_file.

Not in the report: the 19 new deny pieces raise the client-config
counts, which RecordTests.test_the_counts_that_the_record_states_are_the_ones_check_prints
reads from the latest projection in
docs/decisions/2026-10-02-new-wsl-client-configuration.md. A dated
addendum gives the new projection (423 pieces, 383 wired, 172 through a
slot), in that record's established form. The pieces are wired through
the command-output slot by the existing `Bash(rtk *` map entry. The
record's sha256 is pinned only by its own manifest row.

Applies F3.2 of the owed-checks report
~/horizon-build/command-center/claude-native/OWED-CHECKS-2.1.302-20261017.md
(base 90471d6). The host settings are not re-applied here.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins seathatflowsinourveins added the lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers label Oct 17, 2026
seathatflowsinourveins added a commit that referenced this pull request Oct 17, 2026
… each pinned by a test

Fold 4 on 1af2052. Both reads of 1af2052 are done; this commit fixes the four findings the command
center listed from them. Each correction has a regression test that fails, with an AssertionError,
on the text it replaces.

1. P2: F5.2 had no regression test (observation-inference.md:13, slots.json:2107; F5.2 of the
   command center's owed-checks report, OWED-CHECKS-2.1.302-20261017.md). The new class
   UsageCostMonitoringSpanAttributeTests in tests/test_native_practice_owed_check_corrections.py
   checks that the row and the page:
   - lack "is to be added to the collector's tool-name and privacy allowlists";
   - carry "The span attributes need no allowlist entry" and "To be tested, with Claude traces on".
   It also checks that the test line the note cites (tests/test_observability_tool_names.py:178)
   still asserts OTEL_TRACES_EXPORTER "none". Run with only the test file overlaid on 728141f,
   each of its 3 tests fails. They pass at 1af2052, where fold 2 made the correction, and at this
   commit.

2. P3: the L916 sentence ([email protected] L916, 2.1.290) left out F3.2 (token-efficiency.md:51,
   slots.json:785). One sentence is added to the output-compression note, written to the row and
   the page from one string. It says three things:
   - rtk 0.51.0 rewrites every npx command (rtk-ai/[email protected] src/discover/rules.rs:120);
   - none of the 19 `npx *skills` deny rules in the user settings has an `rtk npx` twin;
   - PR #1238 adds the 19 twins to the template.
   The counts come from an exact-key read of permissions.deny at 2026-10-17T04:41:38Z (19 rules, 0
   twins). The repository's own matcher (ProfileTemplateSettingsTests.bash_rule_matches) finds no
   deny rule for six rtk spellings of the skills CLI there, and one for the plain spelling. PR
   #1238's template holds 19 rules and 19 twins at its head 6bf2eb5.
   OutputCompressionRtkNpxGapTests checks that the row and the page carry the sentence after the
   force-push one; both checks fail on 728141f and on 1af2052. It also checks that the template
   still holds 19 `Bash(npx *skills` rules, which stays true after #1238. The slot manifest's
   sha256_when_labeled is the sha256 of this commit's slots.json, taken from sha256sum.
   differs_from_this_snapshot_in is unchanged because notes are not exported
   (test_no_other_exported_field_differs passes).

3. P3: fold 3's "current locator `:1649`" in docs/decisions/2026-10-09-claude-code-gap-resolution.md:174
   would go stale. As the command center ruled, the record is back to main's bytes (git checkout
   origin/main; git diff --quiet origin/main exits 0), because its citation is already pinned to the
   search revision 8c95a50. The evidence row fold 3 added for it is removed; the record has none on
   main. DispositionCitationTests in tests/test_upstream_surface_watch.py already checks this record
   against references that move. It gains two tests:
   - the routines sentence keeps `reference/slots.json:1625` and has no "current locator" (fails on
     1af2052; passes on 728141f and here);
   - line 1625 is "Cloud routines" at 8c95a50 (skipped when the history lacks that revision).

4. P3: the slot manifest's note (claude-native-slot-manifest.json:69) named six slots whose notes
   differ from the snapshot when 21 do. It also named three of the five top-level keys that differ:
   checked_at and client_version differ too, since this PR's first commit. The sentence now names
   fields, not slots: "Slot fields this export does not carry also differ (notes, primary_sources,
   primary_sources_total and github-action's retired block), and so do the top-level checked_at,
   client_version, cross_client, selection_rule and status_values." A new test in
   tests.test_native_practice_snapshot_provenance's BaselineHistoryTests,
   test_the_note_names_what_differs_beyond_the_exported_fields, builds that sentence from the
   baseline and current slots files. On failure it prints the sentence to write; it fails on
   728141f and on 1af2052. The note's other counts hold at this commit: the 2.1.302 update changed
   the evidence of eleven slots and four routes.

Evidence rows: manifests/evidence.json is 450608c's copy, with rows registered through
scripts/host_receipts.register_file for the six files this fold changes and for the fold-3 test.
Against 1af2052 it drops the record's row and refreshes those six. scripts/evidence_manifest.py
--write left it unchanged.

Checks, run with fold 4 in the tree before this commit:
- python3 scripts/validate.py rc 0; python3 scripts/evidence_manifest.py --check rc 0.
- The five acceptance modules, each by name, all OK:
  tests.test_native_practice_ledger_obs_sched (8 tests), tests.test_native_practice_ledger_rows_1 (3),
  tests.test_native_practice_ledger_rows_tokeff_new (7), tests.test_native_practice_snapshot_provenance
  (10) and tests.test_skills_manifest (38).
- The test selection is not capped: grep -rl over tests/ for the basename of every path this PR or
  this fold changes, plus claude-native-practice and slot-manifest, gives 76 modules.
  - 75 ran one at a time and unittest counted 4,324 tests; 66 modules pass.
  - tests.test_runtime_worker_openhands_push_gate, which reads the committed HEAD, runs after this
    commit.
  - The other 9 fail because of this host, not the fold; CI passed every validate shard at 450608c.
- These fail the same way with the tracked tree at 450608c, as measured for fold 3:
  - tests.test_upstream_surface_watch: the same 4 CachedArtifactTests, which read this host's
    surface-watch cache. Its new record tests pass.
  - tests.test_local_pages_overview: the 2 ComposerTests.
  - tests.test_local_pages_architecture_read_boundary and tests.test_local_pages_architecture_sources:
    26 errors each, no /usr/bin/zstd.
  - one test of tests.test_token_e2e_grader: git clone --local across filesystems.
- tests.test_component_matrix, tests.test_final_admission, tests.test_final_stack and
  tests.test_gap_closeouts need jsonschema, which this host's python3 lacks. With fold 4 they pass in
  a Python 3.12 venv built from .github/requirements-ci.txt, as do tests.test_lane_packets and
  tests.test_paired_runs_results.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 17, 2026
…e row; scope the rtk npx sentence

Fold 5 on 609d3e1. Both reads of 609d3e1 requested changes, and the higher rating governs. This
commit fixes the two findings the command center listed.

1. P1 (Muse): the command center corrects ruling 3 of fold 4.
   - docs/decisions/2026-10-09-claude-code-gap-resolution.md stays at main's bytes, but its
     manifests/evidence.json row must not be dropped.
   - Fold 3 (1af2052) registered the record. The PR-registration check requires a row for every
     path a PR commit registered (scripts/validate.py:776 and :786-788). CI runs it with the PR
     base and the previous heads (.github/workflows/validate.yml:173-178). Only a deleted file may
     lose its entry (docs/lanes.md:119-127; the fixtures at tests/test_registry_rows.py:68-84 and
     :112).
   - At 609d3e1, python3 scripts/validate.py --registration-base 1af2052 and
     --registration-base f00d478 each exited 1 with "docs/decisions/2026-10-09-claude-code-gap-resolution.md:
     required registration row missing", and CI's validate-shard-0 failed.
   - scripts/host_receipts.register_file restores the row with the reverted file's current sha256
     and bytes (15899 bytes; the file is unchanged against main).

2. P3 (Claude and Muse): "Every npx command is rewritten too" is false at rtk v0.51.0
   (rtk-ai/rtk@e001f773) for an npx command that a deny rule matches.
   - rtk's Claude hook checks the original command against the Bash deny rules first
     (src/hooks/permissions.rs:84-90) and skips the rewrite on a match
     (src/hooks/hook_cmd.rs:688-691); only the remaining npx commands reach the npx rule
     (src/discover/rules.rs:120).
   - The sentence now limits the rewrite to npx commands that no deny rule matches, and says that
     the twins in #1238 cover the `rtk npx` spelling, which rtk's own deny check does not cover.
   - The edit script reads the sentence from the test's CLAUSE and writes it to
     token-efficiency.md:51 and slots.json:785. The module docstring is scoped the same way.
   - With only the test file overlaid on 609d3e1,
     OutputCompressionRtkNpxGapTests.test_the_row_names_the_gap_and_its_fix and
     test_the_page_carries_the_row each fail with an AssertionError; both pass here.
   - The slot manifest's sha256_when_labeled is the sha256 of this commit's slots.json, taken from
     sha256sum. differs_from_this_snapshot_in is unchanged, because notes are not exported.

Evidence rows: register_file refreshed the rows of slots.json, token-efficiency.md, the slot
manifest and the test module, and restored the record's. scripts/evidence_manifest.py --write left
the file unchanged.

Checks, run with fold 5 in the tree before this commit:
- python3 scripts/validate.py rc 0; python3 scripts/evidence_manifest.py --check rc 0. The
  registration checks read the committed head, so validate.py with --registration-base origin/main
  and with --registration-base 1af2052 runs after this commit; the PR body records the exits.
- The five acceptance modules all pass: tests.test_native_practice_ledger_obs_sched (8 tests),
  tests.test_native_practice_ledger_rows_1 (3), tests.test_native_practice_ledger_rows_tokeff_new (7),
  tests.test_native_practice_snapshot_provenance (10) and tests.test_skills_manifest (38).
- The uncapped selection is the same 76 modules as for fold 4. 75 ran before the commit, in two
  streams, with tests.test_saturation_ledger alone afterwards; unittest counted 4,324 tests.
  - 66 pass, among them tests.test_registry_rows, tests.test_validate and tests.test_host_receipts.
  - tests.test_runtime_worker_openhands_push_gate runs on the committed head.
  - The other 9 are the environment failures recorded for fold 4. Each fails the same way at the
    previous head, or passes in the CI-requirements venv: four CachedArtifactTests, two
    ComposerTests, no /usr/bin/zstd (two modules), one cross-filesystem clone, and four modules
    that need jsonschema.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 17, 2026
…ude Code 2.1.302 (#1234)

* docs(claude-native-practice): bring the practice pages current to Claude Code 2.1.302

Source for every edit: anthropics/claude-code CHANGELOG.md at v2.1.302 (fetched 2026-10-16T22:15Z
with `gh api repos/anthropics/claude-code/contents/CHANGELOG.md -H "Accept: application/vnd.github.raw"`,
sha256 prefix 57fde96b3318543c), cited by line as [email protected] L<n>; each cited line was
checked against the fetched file. The fetched file has no 2.1.297 or 2.1.298 section.

- Headers: slots.md, slots.json and the eleven layer pages move to client 2.1.302, checked
  2026-10-16; cross-client.md is left alone (hash-tested against cross-client-lines.json).
- native-clients.md: settings-permissions records the 2.1.299 rule-evaluation change (L373,
  L280, L245, L270) with an owed audit of prefix-matched mcp__ entries; checkpoints-rewind
  records that 2.1.300 transcripts carry each request (L186) and owes a re-measured footprint;
  model-effort-routing keeps CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL unset too (L411, L224, L371).
- isolation.md: sandbox cites the 2.1.299 and 2.1.300 sandbox changes and has M1 run on
  2.1.302 (L249, L190); the M49 worktree probe moves to 2.1.302 (L153, L148, L77, L324, L157).
- token-efficiency.md: context-compaction records idle compaction, the /config row and
  subagent autoCompactWindow at their defaults (L217-L218, L6, L410, L110); output-compression
  cites Read allow_large, CLAUDE_CODE_DISABLE_FILE_MENTIONS and updatedInput validation (L414,
  L216, L189) and owes an rtk-hook check.
- workers.md: subagent-definitions records the tools: list change and fork subagents on in -p
  (L374, L410, L35, L36); background-workflows routes the 2.1.300 resume through the Workflow
  tool's approval, to be re-observed (L185, L365, L81, L411).
- mcp-surfaces.md: the 4,096-character up-front limit (L469, L377, L142).
- agent-sdks.md: headless-sdk routes the 2.1.302 -p start mode and fork subagents (L34, L35,
  L36, L291).
- observation-inference.md: usage-cost-monitoring lists the new OTel fields for the collector
  allowlists (L126, L130, L75, L76, L18, L467, L186).

slots.json mirrors every page edit (Evidence, Notes and Route match the pages exactly); the
slot manifest's sha256_when_labeled follows slots.json and differs_from_this_snapshot_in gains
the newly differing evidence and route slots; manifests/evidence.json re-registers the changed
files.

Checks: python3 scripts/validate.py rc 0; scripts/evidence_manifest.py --check rc 0; the 13
native-practice test modules ran 347 tests, with the same two ComposerTests failures as on the
base 90471d6 (the overview composer's layer pages hit a ModuleNotFoundError in this
environment) and nothing else.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QcCViiYWLxs4igpJR3yws6

* Correct the Workflow overturn citation and four wording slips in the 2.1.302 practice pages

The CC's Claude-family read of 0b361d4 found one false citation: workers.md and slots.json gave
[email protected] L411 as a Workflow resume or limit change, but L411 (2.1.296) only adds
CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL. The overturn still fired through L365 (2.1.299, the nesting
limit) and L185 (2.1.300, resume through the Workflow tool's approval), so the parenthetical now cites
those two.

Wording now follows the cited lines: the /config Idle compaction row turns idle compaction off or back
on (L6); the 4,096-character figure is the default limit (L469); L34's comma is restored. The
settings-permissions (L373) and headless-sdk (L34, L35) notes now say that their overturn fired, as the
other updated slots do.

slots.json mirrors every edit; the slot manifest's sha256_when_labeled and the seven changed files'
manifests/evidence.json rows were refreshed with scripts/host_receipts.py register_file.
Checks: python3 scripts/validate.py rc 0; python3 scripts/evidence_manifest.py --check rc 0; the 13
test modules that read these pages ran 347 tests with the same two ComposerTests failures as on the
untouched base 90471d6 and nothing else.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(claude-native-practice): the fork toggle is fork-only (GPT read P1 at 887f929)

The headless-sdk row (agent-sdks.md:9 and its slots.json mirror) offered CLAUDE_CODE_FORK_SUBAGENT=0
as an alternative to keeping Agent out of --tools for a worker that must not fan out. [email protected]
L35 says the variable turns off fork subagents (subagent_type "fork") only, so a named subagent can still
fan out. The row now keeps Agent out of --tools as the control and describes the toggle as fork-only.

tests/test_native_practice_fork_toggle.py pins the corrected text (it fails on 887f929 with only the
test overlaid) and the page's mirror of the row. The two files' evidence rows are refreshed through
scripts/host_receipts.py register_file.

Source: anthropics/claude-code CHANGELOG.md at tag v2.1.302, line 35.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(claude-native-practice): record the 2.1.302 owed checks and relabel the slot manifest

A fold on 728141f that applies the PR #1234 diffs of the command center's owed-checks report
(command-center/claude-native/OWED-CHECKS-2.1.302-20261017.md, written 2026-10-17T02:43:07Z). Each
page edit is mirrored in its slots.json row. Rule source: anthropics/claude-code CHANGELOG.md at tag
v2.1.302, cited as [email protected] L<n> with the release each line sits under.

- native-clients.md:53-54, settings-permissions (report F1.1, F1.2): L245 (2.1.299) fixes rm
  prompts on shell -c scripts; it does not change rule evaluation. The evidence and the note now
  cite L373 and L280 for rule evaluation and L245 for the built-in prompt. The owed audit of mcp__
  rules against L373, L280 and L270 (2.1.299) replaces the owed sentence: no rule relied on prefix
  matching, so none changes.
- workers.md:13, subagent-definitions (F2.1, F2.2): the note said four host copies differ from
  adoption/agents/claude and four host-only definitions exist. diff -rq of adoption/agents/claude
  and of .claude/agents against ~/.claude/agents exits 0, 11 files each, so the claim was false at
  728141f. The owed audit of the tools: lists against L374 (2.1.299) is recorded: 25 whole-name
  grants from six servers, and no list changes.
- token-efficiency.md:50-51, output-compression (F3.1): the owed check of the rtk hook against the
  updatedInput validation of L189 (2.1.300) is recorded (rtk-ai/[email protected]
  src/hooks/hook_cmd.rs:648-651 replaces only command), and L916 (2.1.290) joins the evidence.
- mcp-surfaces.md:12-13, mcp-config-tool-search (F4.1): the owed measurement of the up-front
  context at the 4,096-character default of L469 (2.1.296) is recorded, beside L377 (2.1.299);
  L602 (2.1.295) and L1926 (2.1.280) join the evidence.
- observation-inference.md:13, usage-cost-monitoring (F5.2): the note said each new field is to be
  added to the collector's allowlists. It now says neither collector profile keeps the five event
  fields of L126 (2.1.300), L75 and L76 (2.1.301) and L18 (2.1.302), and that the span attributes
  of L130 (2.1.300) need no allowlist entry because the templates export no Claude traces.

The six diffs were applied with git apply after git apply --check (exit 0 each). Each replaced
evidence or notes line occurs once at 728141f; the "]," lines that the slots.json hunks also rewrite
are placed by their context. Each result has the sha256 the report proposes.

Label fix: current_decision_source.sha256_when_labeled in claude-native-slot-manifest.json now names
the sha256 of this commit's slots.json, taken from sha256sum. This corrects 728141f, which changed
slots.json without moving the label, so tests.test_native_practice_snapshot_provenance
(test_the_label_names_the_shipped_slots_file) fails there; the CC had capped its test selection for
that commit. differs_from_this_snapshot_in is unchanged. Of the fields the manifest exports, the fold
changes only evidence, in settings-permissions, output-compression and mcp-config-tool-search, and
the manifest already lists all three. Notes are not exported.

The manifests/evidence.json rows of the seven changed files were refreshed with
scripts/host_receipts.register_file; scripts/evidence_manifest.py --write left the file unchanged.

Checks, run with the fold applied before this commit: python3 scripts/validate.py rc 0;
python3 scripts/evidence_manifest.py --check rc 0. The test modules that name a changed path (grep
-rl over tests/ for each changed file's basename, claude-native-practice and slot-manifest, not
capped) are 72; each ran on its own (unittest counted 4,099 tests). 64 pass, among them
tests.test_native_practice_snapshot_provenance (9 tests) and tests.test_native_practice_fork_toggle
(2). The other 8 fail from this host's environment, not the fold; at 728141f the only test that
failed in CI was the label test. Four fail the same way on the untouched 728141f:
tests.test_local_pages_overview (the 2 ComposerTests failures);
tests.test_local_pages_architecture_read_boundary and tests.test_local_pages_architecture_sources
(26 errors each, no /usr/bin/zstd); and one test of tests.test_token_e2e_grader (git clone --local
cannot hardlink across filesystems). The other four need jsonschema, which this host's python3
lacks: tests.test_component_matrix, tests.test_final_admission, tests.test_final_stack and
tests.test_gap_closeouts. With the fold they pass in a Python 3.12 venv built from
.github/requirements-ci.txt, as do tests.test_lane_packets, tests.test_paired_runs_results and
tests.test_saturation_ledger, whose jsonschema tests had skipped.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* test(claude-native-practice): pin the F1.1 and F2.1 corrections; re-point the Cloud routines locator

Fold 3 on 450608c, at the command center's request after its read of fold 2.

Regression tests: tests/test_native_practice_owed_check_corrections.py, in the style of
tests/test_native_practice_doc_corrections.py, pins the two corrections fold 2 made from the
command center's owed-checks report (command-center/claude-native/OWED-CHECKS-2.1.302-20261017.md).

- F1.1, settings-permissions (SettingsPermissionsRmPromptTests): [email protected] L245 (2.1.299)
  fixes rm prompts on shell -c scripts; it does not change rule evaluation, which L373 and L280
  (2.1.299) do. The slots.json row cites L245 only as "L245 (2.1.299, rm prompts on shell `-c`
  scripts)", its rule-evaluation sentence cites L373 and L280 without L245, and the native-clients.md
  section carries the corrected Evidence and Notes lines and neither of the two wrong phrases.
- F2.1, subagent-definitions (SubagentDefinitionsDriftNoteTests): the note has none of the three
  stale drift phrases and states that the copies match; the workers.md section mirrors it. The
  count of definitions in the corrected sentence equals the files in adoption/agents/claude and in
  .claude/agents, which are byte-identical. Its locator into
  docs/decisions/2026-10-13-claude-agent-drift-check.md names the line that records the old note as
  stale. The host folder ~/.claude/agents is not readable from the repository.

Fail first: with only the test file overlaid on 728141f, each of the 5 tests fails with an
assertion (FAILED (failures=1) each; the module FAILED (failures=5)). At 450608c with the file added,
each passes (module OK).

Locators: /usr/bin/grep -rn over the whole repository, not capped, for the basename of slots.json and
of each of the 12 reference pages this PR changed, followed by :<digits>, finds 103 locators in text
files and one compiled .pyc that git ignores. Only slots.json moved lines in this PR: every hunk in the
pages replaces lines one for one. One live locator into it was stale. The gap-resolution record at
line 174 cited reference/slots.json:1625 for the "Cloud routines" alternative of scheduled-tasks: the
right line at 8c95a50, the revision its search names, and on main. The text is at line 1649 now.
Because the sentence reports that search, the locator keeps :1625 at 8c95a50 and adds "current
locator `:1649`", the form the ecosystem-roadmap record uses (2026-09-28-ecosystem-roadmap.md:357).
Line 1649 is "Cloud routines" in the alternatives of scheduled-tasks. The edit stays on its line, so
the record keeps its 245 lines and its lines 179-181 keep the numbers that the usage-cost-monitoring
note and tests/test_native_practice_ledger_obs_sched.py:85 cite. Its slots.json:3 locator
(client_version) still resolves. The other hits stay as they are:
- 64 sit in evidence/artifacts/claude-native-practice-20261009/primary-source-reading.json. They
  resolve at a30c218, and tests.test_native_practice_snapshot_provenance checks them there. The
  record that describes them (2026-10-09-claude-code-native-practice.md:344) gives slots.md:35 as
  an example and says it resolves at that revision.
- The test comments that cite a review finding of #1001 or #1005 are history.
- The rest name other files whose names end the same way: 2026-09-30-omniroute-runtime-workers.md,
  2026-09-28-openhands-resolver-isolation.md, a docs/token-efficiency.md that this repository has
  never tracked (agent-lab's), and the dated slots.json snapshots under evidence/artifacts.

Evidence rows: scripts/host_receipts.register_file added rows for the two changed files; the
gap-resolution record had none. scripts/evidence_manifest.py --write left the file unchanged.

Checks, run with fold 3 in the tree before this commit: python3 scripts/validate.py rc 0;
python3 scripts/evidence_manifest.py --check rc 0. The test modules that name a changed path (grep
-rl over tests/ for each changed file's basename, claude-native-practice and slot-manifest, not
capped) are now 74. Two are new to the list: the new module, and tests.test_upstream_surface_watch,
which reads the gap-resolution record. unittest counted 4,220 tests. 64 modules pass, among them the
new module (5 tests), tests.test_native_practice_snapshot_provenance (9) and
tests.test_native_practice_fork_toggle (2). The other 10 fail because of this host, not the fold. CI
passed every validate shard at 450608c.
- These fail the same way with the tracked tree at 450608c: tests.test_upstream_surface_watch (4
  CachedArtifactTests, which read this host's surface-watch cache; its record checks pass);
  tests.test_local_pages_overview (the 2 ComposerTests); tests.test_local_pages_architecture_read_boundary
  and tests.test_local_pages_architecture_sources (26 errors each, no /usr/bin/zstd); and one test
  of tests.test_token_e2e_grader (git clone --local across filesystems).
- tests.test_component_matrix, tests.test_final_admission, tests.test_final_stack and
  tests.test_gap_closeouts need jsonschema, which this host's python3 lacks. With fold 3 they pass
  in a Python 3.12 venv built from .github/requirements-ci.txt, as do tests.test_lane_packets and
  tests.test_paired_runs_results.
- tests.test_saturation_ledger lost one V2PendingCliTests test, with "native publication scanner
  unavailable", in each of two runs made while three test streams shared the host. Run alone it
  passes under python3 (OK, skipped=1) and in the venv (OK).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(claude-native-practice): close the four read findings on 1af2052, each pinned by a test

Fold 4 on 1af2052. Both reads of 1af2052 are done; this commit fixes the four findings the command
center listed from them. Each correction has a regression test that fails, with an AssertionError,
on the text it replaces.

1. P2: F5.2 had no regression test (observation-inference.md:13, slots.json:2107; F5.2 of the
   command center's owed-checks report, OWED-CHECKS-2.1.302-20261017.md). The new class
   UsageCostMonitoringSpanAttributeTests in tests/test_native_practice_owed_check_corrections.py
   checks that the row and the page:
   - lack "is to be added to the collector's tool-name and privacy allowlists";
   - carry "The span attributes need no allowlist entry" and "To be tested, with Claude traces on".
   It also checks that the test line the note cites (tests/test_observability_tool_names.py:178)
   still asserts OTEL_TRACES_EXPORTER "none". Run with only the test file overlaid on 728141f,
   each of its 3 tests fails. They pass at 1af2052, where fold 2 made the correction, and at this
   commit.

2. P3: the L916 sentence ([email protected] L916, 2.1.290) left out F3.2 (token-efficiency.md:51,
   slots.json:785). One sentence is added to the output-compression note, written to the row and
   the page from one string. It says three things:
   - rtk 0.51.0 rewrites every npx command (rtk-ai/[email protected] src/discover/rules.rs:120);
   - none of the 19 `npx *skills` deny rules in the user settings has an `rtk npx` twin;
   - PR #1238 adds the 19 twins to the template.
   The counts come from an exact-key read of permissions.deny at 2026-10-17T04:41:38Z (19 rules, 0
   twins). The repository's own matcher (ProfileTemplateSettingsTests.bash_rule_matches) finds no
   deny rule for six rtk spellings of the skills CLI there, and one for the plain spelling. PR
   #1238's template holds 19 rules and 19 twins at its head 6bf2eb5.
   OutputCompressionRtkNpxGapTests checks that the row and the page carry the sentence after the
   force-push one; both checks fail on 728141f and on 1af2052. It also checks that the template
   still holds 19 `Bash(npx *skills` rules, which stays true after #1238. The slot manifest's
   sha256_when_labeled is the sha256 of this commit's slots.json, taken from sha256sum.
   differs_from_this_snapshot_in is unchanged because notes are not exported
   (test_no_other_exported_field_differs passes).

3. P3: fold 3's "current locator `:1649`" in docs/decisions/2026-10-09-claude-code-gap-resolution.md:174
   would go stale. As the command center ruled, the record is back to main's bytes (git checkout
   origin/main; git diff --quiet origin/main exits 0), because its citation is already pinned to the
   search revision 8c95a50. The evidence row fold 3 added for it is removed; the record has none on
   main. DispositionCitationTests in tests/test_upstream_surface_watch.py already checks this record
   against references that move. It gains two tests:
   - the routines sentence keeps `reference/slots.json:1625` and has no "current locator" (fails on
     1af2052; passes on 728141f and here);
   - line 1625 is "Cloud routines" at 8c95a50 (skipped when the history lacks that revision).

4. P3: the slot manifest's note (claude-native-slot-manifest.json:69) named six slots whose notes
   differ from the snapshot when 21 do. It also named three of the five top-level keys that differ:
   checked_at and client_version differ too, since this PR's first commit. The sentence now names
   fields, not slots: "Slot fields this export does not carry also differ (notes, primary_sources,
   primary_sources_total and github-action's retired block), and so do the top-level checked_at,
   client_version, cross_client, selection_rule and status_values." A new test in
   tests.test_native_practice_snapshot_provenance's BaselineHistoryTests,
   test_the_note_names_what_differs_beyond_the_exported_fields, builds that sentence from the
   baseline and current slots files. On failure it prints the sentence to write; it fails on
   728141f and on 1af2052. The note's other counts hold at this commit: the 2.1.302 update changed
   the evidence of eleven slots and four routes.

Evidence rows: manifests/evidence.json is 450608c's copy, with rows registered through
scripts/host_receipts.register_file for the six files this fold changes and for the fold-3 test.
Against 1af2052 it drops the record's row and refreshes those six. scripts/evidence_manifest.py
--write left it unchanged.

Checks, run with fold 4 in the tree before this commit:
- python3 scripts/validate.py rc 0; python3 scripts/evidence_manifest.py --check rc 0.
- The five acceptance modules, each by name, all OK:
  tests.test_native_practice_ledger_obs_sched (8 tests), tests.test_native_practice_ledger_rows_1 (3),
  tests.test_native_practice_ledger_rows_tokeff_new (7), tests.test_native_practice_snapshot_provenance
  (10) and tests.test_skills_manifest (38).
- The test selection is not capped: grep -rl over tests/ for the basename of every path this PR or
  this fold changes, plus claude-native-practice and slot-manifest, gives 76 modules.
  - 75 ran one at a time and unittest counted 4,324 tests; 66 modules pass.
  - tests.test_runtime_worker_openhands_push_gate, which reads the committed HEAD, runs after this
    commit.
  - The other 9 fail because of this host, not the fold; CI passed every validate shard at 450608c.
- These fail the same way with the tracked tree at 450608c, as measured for fold 3:
  - tests.test_upstream_surface_watch: the same 4 CachedArtifactTests, which read this host's
    surface-watch cache. Its new record tests pass.
  - tests.test_local_pages_overview: the 2 ComposerTests.
  - tests.test_local_pages_architecture_read_boundary and tests.test_local_pages_architecture_sources:
    26 errors each, no /usr/bin/zstd.
  - one test of tests.test_token_e2e_grader: git clone --local across filesystems.
- tests.test_component_matrix, tests.test_final_admission, tests.test_final_stack and
  tests.test_gap_closeouts need jsonschema, which this host's python3 lacks. With fold 4 they pass in
  a Python 3.12 venv built from .github/requirements-ci.txt, as do tests.test_lane_packets and
  tests.test_paired_runs_results.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(claude-native-practice): keep the gap-resolution record's evidence row; scope the rtk npx sentence

Fold 5 on 609d3e1. Both reads of 609d3e1 requested changes, and the higher rating governs. This
commit fixes the two findings the command center listed.

1. P1 (Muse): the command center corrects ruling 3 of fold 4.
   - docs/decisions/2026-10-09-claude-code-gap-resolution.md stays at main's bytes, but its
     manifests/evidence.json row must not be dropped.
   - Fold 3 (1af2052) registered the record. The PR-registration check requires a row for every
     path a PR commit registered (scripts/validate.py:776 and :786-788). CI runs it with the PR
     base and the previous heads (.github/workflows/validate.yml:173-178). Only a deleted file may
     lose its entry (docs/lanes.md:119-127; the fixtures at tests/test_registry_rows.py:68-84 and
     :112).
   - At 609d3e1, python3 scripts/validate.py --registration-base 1af2052 and
     --registration-base f00d478 each exited 1 with "docs/decisions/2026-10-09-claude-code-gap-resolution.md:
     required registration row missing", and CI's validate-shard-0 failed.
   - scripts/host_receipts.register_file restores the row with the reverted file's current sha256
     and bytes (15899 bytes; the file is unchanged against main).

2. P3 (Claude and Muse): "Every npx command is rewritten too" is false at rtk v0.51.0
   (rtk-ai/rtk@e001f773) for an npx command that a deny rule matches.
   - rtk's Claude hook checks the original command against the Bash deny rules first
     (src/hooks/permissions.rs:84-90) and skips the rewrite on a match
     (src/hooks/hook_cmd.rs:688-691); only the remaining npx commands reach the npx rule
     (src/discover/rules.rs:120).
   - The sentence now limits the rewrite to npx commands that no deny rule matches, and says that
     the twins in #1238 cover the `rtk npx` spelling, which rtk's own deny check does not cover.
   - The edit script reads the sentence from the test's CLAUSE and writes it to
     token-efficiency.md:51 and slots.json:785. The module docstring is scoped the same way.
   - With only the test file overlaid on 609d3e1,
     OutputCompressionRtkNpxGapTests.test_the_row_names_the_gap_and_its_fix and
     test_the_page_carries_the_row each fail with an AssertionError; both pass here.
   - The slot manifest's sha256_when_labeled is the sha256 of this commit's slots.json, taken from
     sha256sum. differs_from_this_snapshot_in is unchanged, because notes are not exported.

Evidence rows: register_file refreshed the rows of slots.json, token-efficiency.md, the slot
manifest and the test module, and restored the record's. scripts/evidence_manifest.py --write left
the file unchanged.

Checks, run with fold 5 in the tree before this commit:
- python3 scripts/validate.py rc 0; python3 scripts/evidence_manifest.py --check rc 0. The
  registration checks read the committed head, so validate.py with --registration-base origin/main
  and with --registration-base 1af2052 runs after this commit; the PR body records the exits.
- The five acceptance modules all pass: tests.test_native_practice_ledger_obs_sched (8 tests),
  tests.test_native_practice_ledger_rows_1 (3), tests.test_native_practice_ledger_rows_tokeff_new (7),
  tests.test_native_practice_snapshot_provenance (10) and tests.test_skills_manifest (38).
- The uncapped selection is the same 76 modules as for fold 4. 75 ran before the commit, in two
  streams, with tests.test_saturation_ledger alone afterwards; unittest counted 4,324 tests.
  - 66 pass, among them tests.test_registry_rows, tests.test_validate and tests.test_host_receipts.
  - tests.test_runtime_worker_openhands_push_gate runs on the committed head.
  - The other 9 are the environment failures recorded for fold 4. Each fails the same way at the
    previous head, or passes in the CI-requirements venv: four CachedArtifactTests, two
    ComposerTests, no /usr/bin/zstd (two modules), one cross-filesystem clone, and four modules
    that need jsonschema.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant