Skip to content

Measure daily native skill use and test the security-audit trigger cue - #970

Merged
seathatflowsinourveins merged 9 commits into
mainfrom
codex/ns2604-skill-invoke-rate-20261010
Oct 12, 2026
Merged

seathatflowsinourveins merged 9 commits into
mainfrom
codex/ns2604-skill-invoke-rate-20261010

Conversation

@seathatflowsinourveins

@seathatflowsinourveins seathatflowsinourveins commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

Track daily native skill invocations by client and lane, expose counts in Fleet, register the native Claude API plugin, and keep the measured security-audit routing cue project scoped. Absent Codex roots read UNKNOWN; separately managed native plugins are excluded from default bootstrap and acceptance, while their status checks honor CLAUDE_CONFIG_DIR.

  • Current landing main base: c735e8b2e7d096475ceed380ce956b9191af508c.
  • Lane: lane:foundation.
  • Current carried head: dbccd042068a7c15cbeefe54a89be85053b8a318; reviewed head before carry: 3a402a52bf49802429a654f9d413c3024b2db712.
  • Owned paths: skill-usage and adoption tools, maintained tests, routing fixtures, decision records, catalogs and native evidence registrations.

Reviewed landing rebase after #1013 — historical at 3a402a5

Rebased once on the CC's release onto captured main ccff8765bf91aa02c0c4addad25d680d32abac89. #1013's policy-derived expected_count takes over: tests/test_local_pages_policy_grants.py is identical to captured main, with no PR edit and no grant-count literal. Native inventory_paths gives 95 expected = 95 actual grants, with no missing or extra path. The landing record and its source/base assertion now bind the measured rebased input above.

The advisory baseline is re-derived through existing GitTree / derive_ci_protected on that input. Main's 332-read baseline stays intact; current accounting remains 342 advisory unclassified reads, ten added status observations and three location-only installer moves, with the same exact script/shape classifications and no permission change. The source binding is refreshed through native derivation.

Hot-file conflicts use main's evidence registry followed by native registration of the PR's owned files; no evidence entry is hand-merged. Native component-matrix and new-host-grand-list write commands produce no additional file changes. Every captured-main registry path remains present. The 95-grant record and 54 changed evidence-registration rows land in final integration commit 3a402a52bf49802429a654f9d413c3024b2db712; cda8f6de85941787be7d331ac068ba28343978ac is its rebased measured source input, rather than the complete validation fix.

Pure-rebase stable patch identity outside evidence.json and the grant test is unchanged: 6b10ab6ec30a149edefde9d43c6acb116826790c. After the required provenance/registration commit, that identity changes only for the delta source, landing record and base assertion. Excluding those three declared provenance files as well, implementation patch identity remains cdf2cfedd1d9f67f5be8d5d314df8c89aaae2e62 in both arms. The complete range-diff and both identity results are retained in the packet.

Both original landing-gate methods still fail at exact historical82bb95d1 (two failures, zero errors) and pass at this final head. Earlier blocker fixes remain unchanged: absent-root UNKNOWN, default native-plugin exclusion in every installer mode, 28 managed bootstrap skills, explicit-plugin selection refusal, and real-environment custom-config resolution.

Landing carry after #1011

The grant record was re-derived at input 900a40a6b806228cfbe0ebafc16408b5bff69c82 on this carry base through the maintained test’s native inventory_paths: 97 expected = 97 actual grants, with no missing or extra path. The correction table, expected count, actual count and current grant summary each move from 95 to 97; historical measurements below retain their earlier explicit input bindings. This corrects the reproduced shard-3 failure at the carry head; it does not change the policy or grant test. The test fails at 900a40a6b806228cfbe0ebafc16408b5bff69c82 (exit1) and passes after the amendment at dbccd042068a7c15cbeefe54a89be85053b8a318 (exit0). The full four-test claim module passes, final-stack check exits0, integrity validation passes70 components /11,726 hashes /four profiles /239 receipts, and native Gitleaks passes the nine-commit PR range with zero leaks.

Rebased the nine reviewed commits onto #1011's landed main c735e8b2e7d096475ceed380ce956b9191af508c, with an exact lease on the reviewed 3a402a52bf49802429a654f9d413c3024b2db712 head. Only manifests/evidence.json conflicted; the native main-copy and 54-file registration path resolved it. The implementation is unchanged outside the registry and the CC-approved carry-kind-2 derived value.

final-stack.json regenerated by final_stack.py --write after the rebase, forced by this PR's skills-lifecycle.json row. The generated catalog changes only the source hash for catalogs/landscape/skills-lifecycle.json; its one evidence registration is refreshed. Output matches an independent native preview byte-for-byte. final_stack.py --check exits0 after regeneration, and the CC's carry check will byte-compare a fresh write at the new head.

Final carried head: dbccd042068a7c15cbeefe54a89be85053b8a318. validate.py passes70 components /11,726 hashes /four profiles /239 receipts. Native Gitleaks8.30.1 passes the nine-commit PR range with zero leaks. Range-diff rows1-8 are equal outside the registry;row9's sole extra delta is the explicitly approved generated catalog hash. All nine rows are equal when that derived output is excluded too. No implementation or test change accompanies this carry. Historical measurements and earlier full-suite results below retain their original input bindings.

SOTA sources

  • Native derivation source at the captured main base at native-agent-stack@ccff8765bf91aa02c0c4addad25d680d32abac89: scripts/local_pages_policy_grants.py (inventory_paths), blueprints/runtime-workers/openhands/resolver/push_gate.py (GitTree / derive_ci_protected), and scripts/validate_shards.py (run / aggregate). These existing supported mechanisms supply the correction and its full-suite coverage proof.

  • Official Claude Code environment variables, CLAUDE_CONFIG_DIR row; live/unmirrored capture read 2026-10-11, SHA-256 8097c27c0a5dd4b3428a61a9d3a79eb33b57c8eb30a3e5422d471d64c98f515f, retained unmodified with the packet.

  • native-agent-stack@878f2891aaa9027b10b7af3e4321ef5e882eedd0: scripts/build_new_wsl_handbook.py, derived from scripts/build_ecosystem.py@20ea4ae23a18565676823b9e3a23541c2100bb39. Used through supported --write/--check and digest APIs for the handbook source-digest refresh.

  • scipy/[email protected]: scipy/stats/_stats_py.py, fisher_exact, used through the upstream scipy.stats.fisher_exact API in an isolated uv run --with scipy==1.17.1 environment to verify the three same-HEAD p values. This is a statistical replay of retained counts, not a new model run.

  • anthropics/skills@dbd4588f9e1033efb41dad4bef2f7947c8993d44: official marketplace entry, claude-api SKILL.md, and LICENSE.txt. Public source and installed native cache agree on the digest, directory pin and namespace.

  • Installed Claude Code 2.1.296 and anthropics/claude-code@2301018b1f61073c501a8e7a4813ef48c239163b: release history, native skill discovery, visibility controls, and native eval fixtures, read 2026-10-10. Visibility settings cannot replace descriptions or govern plugin skills.

  • Anthropic skill-creator description guidance, skills/skill-creator/SKILL.md:52,67; mirror HEAD checked against live upstream at the same pin. The trigger/exclusion pattern also cites openai/skills@49f948faa9258a0c61caceaf225e179651397431 security-best-practices and security-threat-model descriptions, preserving cloudflare/security-audit-skill@c1c8a8c1471069fb0e188eeaff69b8e8db6564a8 unchanged.

  • Existing main implementation e1c88ff3d7edc71052d6fb4eed8422438b06efaf: tools/skill-usage/skill_usage.py and examples/claude-native/workflows/child-usage.mjs. The daily adapter calls these collectors and projects their counts.

  • systemd/systemd@b3d8fc43e9cb531d958c17ef2cd93b374bc14e8a (v259.5): calendar/Persistent semantics, user verification and the repository's live-clone placeholder convention.

Evidence-class table

Claim Evidence class Command / receipt
Native inventory is exactly 97 reviewed grants; advisory gate accounting is 342 against the retained 332 baseline local_integration Native inventory selector, native GitTree/derive_ci_protected replay, full policy and gate modules
Absent-root UNKNOWN, fresh-plugin tracking and custom-config recovery synthetic Four maintained blocker methods; exact reviewed-source fail-before replay and current fixture controls
Final integrity and generated-output contracts local_integration FULL validate, evidence_manifest, full handbook and related modules
Routing effect size synthetic Retained CC hermetic same-checkout model experiment and hashed count receipts below; no new model run in this correction
Source bindings and native plugin namespace source_review Pinned sources above and retained source archives

Retained primary effect size: same-checkout hermetic ablation

Use the one-checkout ablation for the primary effect size. Its arms share one HEAD and change only the inline skillOverrides.native-skill-routing setting. Primary citation, independently rehashed: ~/.local/state/native-agent-stack/research/cc-native-practice-20261009/trigger-cases-20261010/ABLATION-TABLE.md, 2724 bytes, SHA-256 770555cb65e58c0143991faf6220bf3c29e78cec671e2e274e48effd5304e179.

This hermetic comparison ran 128 sessions on the same checkout, with the cue listed in 64/64 on transcripts and 0/64 off transcripts. Security-audit turn one increases 13/20 hidden to 20/20 listed, a 35 percentage point observed increase (Fisher two-sided p=0.008); invocation within three turns increases 17/20 to 20/20 (p=0.23). The indirect sibling is invoked 12/12 in both arms and in turn one 8/12 hidden versus 12/12 listed (p=0.09), with security-audit capture 0/12 in both; explicit sibling 4/4 and near misses 0/28 in each arm. The earlier source verification checked all eight primary receipt/summary hashes and all twelve supporting-table receipt/summary hashes; this final code correction does not claim a fresh corpus rescan. SciPy 1.17.1's upstream scipy.stats.fisher_exact independently reproduces p=0.008316008316008316, 0.23076923076923084 and 0.09316770186335403. The cue and exclusion conclusion stands within these synthetic-task limits.

The CC's 21:22Z method correction identifies HEAD-subject priming in the git-status context: it reports the stale-tree control firing 7/8 under a retirement-related subject versus 2/11 under its own subjects. The three-arm study's arms differ by HEAD subject, so its effect size is overstated. Its counts remain supporting evidence; they do not supply the primary effect estimate.

Measurement rule: future A/B arms must be hermetic and share one HEAD, with skillOverrides toggled on the same checkout. If a tree-switch control requires an empty commit, use the same subject in both arms and record HEAD/subject equivalence; differing commit subjects must not prime the git-status context.

Local commands run — historical at 3a402a5

  • Exact historical82bb95d1 gate replay: two failures, zero errors, exit1 (92 !=94 and baseline SHA mismatch).
  • Both required gate methods at this committed head: two tests passed, exit0 (7.697s).
  • Landing-record module, native grant-policy module and repository advisory-gate class: 32 tests passed, zero skips, exit0.
  • python3 scripts/validate.py: exit0, 70 components / 11,709 hashed files / four profiles / 239 receipts.
  • Native registration, component-matrix/grand-list write, manifest check and diff check: exit0.
  • Gitleaks8.30.1: nine-commit PR range only, zero leaks, exit0; normal commit and pre-push hooks retained.

Historical full-suite verification at84131271 remains retained: all341 modules /13,093 tests, zero failures/errors and1,134 skips, native aggregate exit0 on that head's exact proposed tree. It is not represented as a fresh full-suite run on this rebased head. The current released rebase is verified by the maintained gate modules and integrity checks above.

Packet: retained local packet pr970-final-rebase-20261011/, including range-diff, pure/final patch identities, native derivation, exact red/green proofs and final report. Prior full-suite and fail-first packets remain unchanged. Astra reads this final head once; the CC's Claude delta and carry/landing are CC-owned. No extra review/model dispatch.

Decision record

docs/decisions/2026-10-10-daily-skill-invoke-rate.md, including the correction-source table, final landing integration and final fail-first contracts.

Host evidence

Host evidence files are outside this change. Timer/profile application remains a separate CC-owned step after landing; no new provider, model or service run is claimed by this correction.

Checklist

  • Required SOTA sources are recorded and pinned.
  • Native evidence registrations and full validation pass.
  • Fail-before regressions cover every final blocker.
  • Existing workflow pins and permission boundaries are preserved.
  • No new secret, paid hosting or billing surface is introduced.
  • Peer-owned worktrees and untracked files are preserved.

Follow-ups

  • Audit the legacy host report's root-availability semantics; its pre-existing configured-root predicate remains separate from the corrected daily projection.

  • Guard malformed public replay input so the daily collector follows its normal unavailable-report path (GPT P3).

  • Align the routing README with the corrected zero-call interpretation: check wiring rather than infer absence of demand (GPT P3).

  • Re-run live-base adjudication transport additions with an external blind-copy scratch location (GPT P3; merge-only verification gap).

  • Return a normal status failure for list-shaped native plugin registries instead of AttributeError (Claude F1 / Codex registry thread, P3).

  • Support CLAUDE_CODE_PLUGIN_CACHE_DIR in native plugin status resolution (Claude F2, P3; host configuration not reproduced).

  • Clarify the present-tense 332-read wording in the historical 90fab19 integration paragraph (Claude F3, P3); current final advisory accounting is 342.

  • Replace the landing regression's copied base literal with a check bound directly to Git (last Claude micro).

  • Separate informational line moves from true additions in the gate delta's location list (last Claude micro).

  • Verify complete skill trees before staging routing evaluations (Codex stage_routing_eval.py:22; final-scope follow-up).

  • Expire stale daily reports' measured flags (Codex fleet_data.py:920; not reproduced in the confirmation read).

  • Align use-group classification with the lane collector (Codex skill_usage.py:489; not reproduced in the confirmation read).

  • Exclude Codex-disabled skills from zero-use candidates (Codex daily_skill_usage.py:90; final-scope follow-up).

  • Disclose the default routing-skill installation in profile entry-point descriptions (Codex install_claude_profile.py:490).

  • Verify the routing target's availability before installing the user-profile router (Codex install_claude_profile.py:196).

  • Reject shared copies of native Claude plugins during status resolution (Codex skills_status.py:640, final-scope follow-up; thread classified and resolved).

  • Check the advisory delta’s added_locations and removed_locations against the native derivation; the maintained gate test currently covers classifications and script/shape/total accounting without validating those location lists (Claude delta P3-1).

  • Correct the decision record’s 94→95 grant attribution: Check active model selectors against a versioned native catalog #943 (c4c56da1, active_model_currency.py) supplied main’s 94th grant; Derive repository grant count from reviewed policy #1013 supplies the policy-derived count assertion. Preserve the measured counts while correcting that provenance (Claude delta P3-2).

  • Restore the displaced AgentGapTests docstring (carried Claude P3).

@seathatflowsinourveins seathatflowsinourveins added the lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers label Oct 10, 2026
@seathatflowsinourveins
seathatflowsinourveins force-pushed the codex/ns2604-skill-invoke-rate-20261010 branch from 3f562fa to 90fab19 Compare October 10, 2026 19:16
@socket-security

socket-security Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Dependency limit exceeded — report not shown.

This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report.

Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard.

Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account.

@seathatflowsinourveins
seathatflowsinourveins force-pushed the codex/ns2604-skill-invoke-rate-20261010 branch 2 times, most recently from 7a1d33e to 52cbf6a Compare October 11, 2026 04:59
@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-11T18:35:12.082593Z 31171fc Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52cbf6ac34

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/adoption/install_skills.py Resolved
Comment thread tools/adoption/install_skills.py Resolved
Comment thread scripts/skills_status.py Resolved
Comment thread tools/skill-usage/daily_skill_usage.py Resolved
@seathatflowsinourveins
seathatflowsinourveins force-pushed the codex/ns2604-skill-invoke-rate-20261010 branch from 52cbf6a to d38ab63 Compare October 11, 2026 16:42
@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d38ab63b76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/skill-usage/stage_routing_eval.py Resolved
Comment thread tools/local-pages/fleet_data.py Resolved
Comment thread tools/skill-usage/skill_usage.py Resolved
Comment thread scripts/skills_status.py Resolved
@seathatflowsinourveins
seathatflowsinourveins marked this pull request as ready for review October 11, 2026 17:05

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d38ab63b76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/test_new_wsl_client_config.py Resolved
Comment thread tools/skill-usage/daily_skill_usage.py Resolved
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so @, an
encoded dot (%2E or .), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins
seathatflowsinourveins force-pushed the codex/ns2604-skill-invoke-rate-20261010 branch from d38ab63 to 31171fc Compare October 11, 2026 18:17
@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31171fc05a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/skills_status.py Resolved
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
Both rendered services now set CPUWeight=idle, Nice=19 and
IOSchedulingClass=idle, the CC's host-capacity T2 result: test and
measurement runs yield to interactive work. IOSchedulingPriority=7 goes,
because the idle I/O class takes no priority level.

systemd 259 systemd.resource-control(5) maps CPUWeight=idle to the cgroup
v2 cpu.idle attribute, and systemd.exec(5) documents Nice= (-20 to 19) and
IOSchedulingClass= (realtime, best-effort or idle). On this host (cgroup v2;
the user manager delegates cpu, memory and pids), a transient user service
with these properties read cpu.idle 1, nice 19 and the idle I/O class,
against 0, 0 and "none: prio 0" for a default service.

tests/test_skill_usage_units.py asserts the three settings in both
services; the assertion failed on the previous templates. The skill-usage
README states the idle class and now names every command_center_skills
input (the three reports, #970's skill-invoke-rate-latest.json and the
practice slots); its evidence.json entry is rehashed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
Both rendered services now set CPUWeight=idle, Nice=19 and
IOSchedulingClass=idle, the CC's host-capacity T2 result: test and
measurement runs yield to interactive work. IOSchedulingPriority=7 goes,
because the idle I/O class takes no priority level.

systemd 259 systemd.resource-control(5) maps CPUWeight=idle to the cgroup
v2 cpu.idle attribute, and systemd.exec(5) documents Nice= (-20 to 19) and
IOSchedulingClass= (realtime, best-effort or idle). On this host (cgroup v2;
the user manager delegates cpu, memory and pids), a transient user service
with these properties read cpu.idle 1, nice 19 and the idle I/O class,
against 0, 0 and "none: prio 0" for a default service.

tests/test_skill_usage_units.py asserts the three settings in both
services; the assertion failed on the previous templates. The skill-usage
README states the idle class and now names every command_center_skills
input (the three reports, #970's skill-invoke-rate-latest.json and the
practice slots); its evidence.json entry is rehashed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
Both rendered services now set CPUWeight=idle, Nice=19 and
IOSchedulingClass=idle, the CC's host-capacity T2 result: test and
measurement runs yield to interactive work. IOSchedulingPriority=7 goes,
because the idle I/O class takes no priority level.

systemd 259 systemd.resource-control(5) maps CPUWeight=idle to the cgroup
v2 cpu.idle attribute, and systemd.exec(5) documents Nice= (-20 to 19) and
IOSchedulingClass= (realtime, best-effort or idle). On this host (cgroup v2;
the user manager delegates cpu, memory and pids), a transient user service
with these properties read cpu.idle 1, nice 19 and the idle I/O class,
against 0, 0 and "none: prio 0" for a default service.

tests/test_skill_usage_units.py asserts the three settings in both
services; the assertion failed on the previous templates. The skill-usage
README states the idle class and now names every command_center_skills
input (the three reports, #970's skill-invoke-rate-latest.json and the
practice slots); its evidence.json entry is rehashed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins
seathatflowsinourveins force-pushed the codex/ns2604-skill-invoke-rate-20261010 branch from 8413127 to 3a402a5 Compare October 11, 2026 22:33
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
Both rendered services now set CPUWeight=idle, Nice=19 and
IOSchedulingClass=idle, the CC's host-capacity T2 result: test and
measurement runs yield to interactive work. IOSchedulingPriority=7 goes,
because the idle I/O class takes no priority level.

systemd 259 systemd.resource-control(5) maps CPUWeight=idle to the cgroup
v2 cpu.idle attribute, and systemd.exec(5) documents Nice= (-20 to 19) and
IOSchedulingClass= (realtime, best-effort or idle). On this host (cgroup v2;
the user manager delegates cpu, memory and pids), a transient user service
with these properties read cpu.idle 1, nice 19 and the idle I/O class,
against 0, 0 and "none: prio 0" for a default service.

tests/test_skill_usage_units.py asserts the three settings in both
services; the assertion failed on the previous templates. The skill-usage
README states the idle class and now names every command_center_skills
input (the three reports, #970's skill-invoke-rate-latest.json and the
practice slots); its evidence.json entry is rehashed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins
seathatflowsinourveins force-pushed the codex/ns2604-skill-invoke-rate-20261010 branch from 3a402a5 to 900a40a Compare October 12, 2026 02:28
@seathatflowsinourveins
seathatflowsinourveins force-pushed the codex/ns2604-skill-invoke-rate-20261010 branch from 900a40a to dbccd04 Compare October 12, 2026 02:44
@seathatflowsinourveins
seathatflowsinourveins merged commit 900835c into main Oct 12, 2026
35 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the codex/ns2604-skill-invoke-rate-20261010 branch October 12, 2026 03:14
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
…tration landscape on the command-center page

The owner asked for the whole ecosystem on one page, so the command center
grows from six sections to nine, still from existing producers only:

- Orchestration: the CC's recorded orchestration-frameworks resolution and
  the same slot in cc-native-practice slots-final.json, the landing queue,
  the co-op's GPT read queue (read-queue-now.json) and the Adoption
  snapshot's orchestration tool calls by role.
- Resolution landscape: each matrix winner's component, pin, evidence class,
  lifecycle stages and platforms, with the W6 final columns (verdict, run
  pin, upstream E2E at the pin, invoke evidence) as recorded or "not
  recorded". Each winner's repository is matched to cc-now.json
  mirrors.pins by the version its tag names or a commit prefix, and a
  winner without a mirror says so. Terminal states come only from
  final-stack.json and read "pending #1008/#1007" until it exists. The
  committed north-star readiness layers follow with the same columns; the
  CC's program, mirrors, rulings and ten-layer plan render as given.
- SOTA skill invoke rates: one row per skill pinned in
  adoption/skills/manifest.json (source@ref, linked only for https, and
  path), joined with the 7-day counts per client from skill_usage.py and
  child-usage.mjs, or from #970's skill-invoke-rate-daily/1 projection when
  it is current. Zero calls flag "wiring defect"; a pinned skill with no
  install record is "not installed" (unknown while /skill-doctor is
  unmeasured); a called skill the manifest does not pin is "unpinned". The
  practice-slot table marks the orchestration-frameworks row. An unmeasured
  value never reads as zero.
- Tokens saved: tools/local-pages/token_tools_now.py runs each token tool's
  own report command (rtk gain, headroom agent-savings and output-savings,
  context-mode doctor) and records its exit code, run time, version and
  own estimate in token-tools-now.json. The page shows each beside its
  command, labels the token-window counters as client counters, and never
  sums across tools, evidence classes or windows.
- Research queue: research-queue.tsv rows and research-state.json's resume
  order.

The #1012 Claude read's fixes are folded in. B1: the email mask moves into
the shared sanitizer and matches after its per-token decoding (CPython
html.unescape and urllib.parse.unquote, cited at v3.13.16), so &commat;, an
encoded dot (%2E or &#46;), %2540 and a semicolon-less &#64 are omitted on
every page; the old page-local mask left all five readable. B2: each
section's label follows what it renders, and every partial section names
its reason. B3: each section and the count strip render in their own guard,
so a scalar codex_top_lanes_M or an integer above 1e308 degrades only its
own section. The receipt lists only the not-wired inputs the page rendered.

source_policy.json gains a command_center role map with sixteen exact repo
and state paths, read through CommandCenterReads, which extends the
Architecture reader (bounded, no-follow, protected names, no user root).
Reports past their limit read "stale" with their age; times recorded as a
time of day stay as recorded.

tools/skill-usage/render_units.py renders reviewed user units that keep the
three skill reports current: hourly, the host report (91 s measured,
including the $0 zero-turn claude -p /skill-doctor, with --claude-timeout
120 because the 30 s default expired once under load) and the Claude lanes
sweep (198 s and a 1.9 GB peak, projected from 181 MB to 26 KB by
systemd/claude-lanes.jq); daily, the Codex lanes report, which had not
finished after 25 minutes, so its completion time is unmeasured. Each step
renames a finished report into place.

The evidence manifest records the new hashes of source_policy.json and the
skill-usage README. Tests cover each section, unknown versus zero,
staleness, hostile types and strings, privacy (eight email forms, decoded
twice) and the exact grants; 33 fail-before mutations of this change each
fail them. The unit tests round-trip each ExecStart through systemd quoting
and pass systemd-analyze verify.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
Both rendered services now set CPUWeight=idle, Nice=19 and
IOSchedulingClass=idle, the CC's host-capacity T2 result: test and
measurement runs yield to interactive work. IOSchedulingPriority=7 goes,
because the idle I/O class takes no priority level.

systemd 259 systemd.resource-control(5) maps CPUWeight=idle to the cgroup
v2 cpu.idle attribute, and systemd.exec(5) documents Nice= (-20 to 19) and
IOSchedulingClass= (realtime, best-effort or idle). On this host (cgroup v2;
the user manager delegates cpu, memory and pids), a transient user service
with these properties read cpu.idle 1, nice 19 and the idle I/O class,
against 0, 0 and "none: prio 0" for a default service.

tests/test_skill_usage_units.py asserts the three settings in both
services; the assertion failed on the previous templates. The skill-usage
README states the idle class and now names every command_center_skills
input (the three reports, #970's skill-invoke-rate-latest.json and the
practice slots); its evidence.json entry is rehashed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
classify_skill and unlocked_folder_differs (the wording of a refusal) both asked whether the installed SKILL.md is the pinned one, and the second copy added two reads to the push gate's monitoring baseline (tests.test_runtime_worker_openhands_push_gate; lines 315 and 317 of the earlier head). One helper, installed_skill_md_matches, now holds the check, so the installer keeps the baseline's five unclassified reads and neither the dated baseline nor #970's dated delta, which pins the baseline's bytes, is touched. Behavior-neutral: the same file and the same sha256 comparison, for project and global scope.

The new test patches the helper and requires classify_skill and the refusal wording to follow it in both directions (it errors on the earlier commit, where the helper does not exist).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
… skill (#1024)

* Require the Claude Code link in the installer's ok state for a global skill

tools/adoption/install_skills.py --check-only reported ok for typesafe-ai on 2026-10-11 while ~/.claude/skills had no entry for it: the global ok state stopped at the canonical folder and the lock entry. scripts/skills_status.py failed the skill (claude_link missing) and a fresh headless Claude Code session did not list it.

The global ok state now also needs the link the Skills CLI makes for a non-universal agent (vercel-labs/skills@7407f389 src/installer.ts L395-426, createSymlink L227-293): a missing link is drift (install: --check-only prints missing-or-drifted and exits 1, --dry-run plans the pinned add, a real run repairs it); an entry in its place that does not resolve to the canonical folder (a real folder, a link to another folder, a dangling link elsewhere) is local content that the CLI would replace (L255-263), refused as local-modified unless --force, as in project scope; the post-add verification re-checks the link, so an add that leaves none is rolled back. A Codex-only entry and a Claude-Code-only copy need no separate link.

Seven new tests (five fail on the unmodified installer, two are controls) and nine mutants, all killed; the one hand-built "already installed" fixture of the idempotent-skip test gets the link a finished add leaves. One paragraph of adoption/skills/lifecycle.md states the contract; the registrations come with the last commit.

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

* Protect the Claude entry on every global install, name the causes, cite the CLI lines by function

The review wave of 114d539 (the Codex review in GitHub, three threads; the command center's Claude read, PASS_WITH_P3; Astra's first read, CHANGES_REQUESTED with one P1, the same protection gap):

P1, protection (Codex thread 1; the read's P3-1 and F1): the Claude entry check ran only for a locked entry, so a first install or an unlocked canonical folder at the pin could still make the CLI replace a folder or a foreign link at ~/.claude/skills/<name> (createSymlink, L255-263, a folder recursively) without --force. The check now comes before the lock: such an entry is local-modified for every global install, as in project scope. The resolve is no longer strict, so a dangling link that points at the canonical folder (the CLI's own, from a half-removed install) is not foreign.

P2, copy fallback (Codex thread 2, ruled not taken by the command center): when the CLI cannot create the symlink it copies the skill into the Claude folder (L428-440). scripts/skills_status.py fails that layout (not_a_symlink), so the installer keeps requiring the link; the rollback now names the cause (no link, or the copy fallback) instead of a generic mismatch.

P1, cited lines (Codex thread 3, false for the pinned blob): src/installer.ts at 7407f389 is git blob 71ebe2aa, 43,226 bytes, equal to the tree entry. The citations now also name the function and quote the statement, the files that decide Codex (universal, agents.ts L227, L910-912) and Claude Code (L158), and the dispatch that makes installSkillForAgent the function for every source of the manifest outside the vercel-labs ones (add.ts L1370-1392, L1978).

P3-2 of the read: the --force help text names the global Claude entry it now overwrites. P3-3: a refusal names every local content it protects (the Claude entry and an unlocked SKILL.md that differs from the pin).

Tests: this commit adds a protection matrix (six states: nothing installed, unlocked canonical folder at the pin or edited, a lock of an older tree, a lock at the pin with an edited or no canonical folder; three kinds of entry: a real folder, a foreign link, a dangling link; 18 subtests, 15 fail on 114d539; each asserts no add, the whole local entry intact, and --force replacing it), the own-link and unresolvable-link guards, the copy-fallback cause test, the refusal-reasons test and a help assertion. Against 114d539's installer the class's 12 tests give 18 failures, all in the tests this commit adds (15 matrix subtests, 2 refusal-reasons subtests, the copy-fallback cause test). Twenty mutants of the new code, none survives.

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

* Share one SKILL.md check between classify_skill and the refusal wording

classify_skill and unlocked_folder_differs (the wording of a refusal) both asked whether the installed SKILL.md is the pinned one, and the second copy added two reads to the push gate's monitoring baseline (tests.test_runtime_worker_openhands_push_gate; lines 315 and 317 of the earlier head). One helper, installed_skill_md_matches, now holds the check, so the installer keeps the baseline's five unclassified reads and neither the dated baseline nor #970's dated delta, which pins the baseline's bytes, is touched. Behavior-neutral: the same file and the same sha256 comparison, for project and global scope.

The new test patches the helper and requires classify_skill and the refusal wording to follow it in both directions (it errors on the earlier commit, where the helper does not exist).

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

* Refuse a canonical link in the installer's ok and install states

claude_link_problem took equal resolved paths of the Claude entry and the
canonical path as proof that the entry was the CLI's own link. When the
canonical path is itself a link onto a real Claude folder, the add removes
that link first (skills@7407f389 src/installer.ts L389) and createSymlink then
removes the Claude folder with the files in it (L263); the pinned CLI v1.7.0
deleted them in a scratch home.

A canonical path that is a link is now local content: local-modified without
--force whatever the lock says, and the refusal names it and the Claude entry.
A link on a parent folder (L240-250), Codex-only entries and Claude-only
copies are unchanged. Other files beside a pinned SKILL.md in the canonical
folder stay unprotected and are named as such (the next change of this lane).

The wording findings of the delta read fold in: the qualifier "an entry that
does not resolve to the canonical folder" in the docstring and lifecycle.md,
and the L428-440 anchor.

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

* Register the files of this change on the current main

The registry rows of tools/adoption/install_skills.py, tests/test_install_skills.py
and adoption/skills/lifecycle.md, recomputed against main after the rebase.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
… measured limits, and run it from the live clone

CPA-C-002 of the Claude-family practice audit (claude-practice-audit-claude-20261012, finding G3-01) and the command center's ruling of 2026-10-12: the per-skill invoke record of #970 was not running, and
would not have run as templated. Three things failed, each measured on the host:

- The /skill-doctor capture hit the 30 s default of skill_usage.py (it takes about 19 s on a quiet host and about 60 s at three runnable threads per CPU) and the daily run had no way to give it more. The
  default is now 300 s (DEFAULT_CLAUDE_TIMEOUT) and the daily run takes --claude-timeout.
- The run exited 2 unless `git branch --show-current` printed `main`, and the clone the unit renders for, ~/code/native-agent-stack-live, is a detached worktree of origin/main
  (docs/decisions/2026-10-09-claude-review-worker.md). The test is now "HEAD is a commit of origin/main" (`git merge-base --is-ancestor HEAD origin/main`, git-merge-base.adoc at git/git@67ad42147a), for
  the collection and for --render-units alike: a feature branch, a commit of the clone's own and a clone with no origin/main are refused with a fixed message.
- One run held the Claude and the Codex scans behind one exit status: as a transient user unit it took 23 min 57 s and exited 1, because the Codex lanes scan alone takes 25 min 47 s. The daily run is now two
  halves, `--half claude` (the /skill-doctor capture and the Claude lanes sweep) and `--half codex` (the host report's Codex scan and the lanes report), each its own user unit with its own record
  (skill-invoke-rate-claude-latest.json, skill-invoke-rate-codex-latest.json), `measured` holding only its own keys and the exit status standing for them. After its record, a half refreshes the combined
  skill-invoke-rate-latest.json that the Fleet page reads, merged from its own record and the other half's newest (the older of the two stamps, a missing or foreign record is an absent half). A slow Codex scan
  can no longer leave the Claude half unmeasured, and a timeout marks only its own half.

Limits per command, from transient-unit measurements on the host: the capture 19.9 s (limit 360 s with its margin), the Claude lanes sweep 2 min 18 s (600 s), the host report's Codex scan 1 min 10 s (600 s), the
Codex lanes scan 25 min 47 s (3,120 s, twice its wall, the command center's rule). TimeoutStartSec of each unit exceeds the sum of its half's limits by a minute (17 min and 63 min; a test pins it;
oneshot units have no start timeout unless one is set: systemd/systemd@e846bbad04 man/systemd.service.xml L682-L689). The units run at 09:30 and 10:00 UTC (OnCalendar with the literal UTC timezone,
man/systemd.time.xml L254-L256), inside the quietest span of the host's load by hour (08:00 to 13:00 UTC).

End to end, rendered from a detached worktree of origin/main and run as transient units: the Claude half 2 min 43.9 s (exit 0, host and claude measured), the Codex half 28 min 3.6 s (exit 0, codex measured), the
combined record measured for all three keys, mode 0600.

Fail-first: the 28 tests of tests.test_skill_usage_daily give FAILED (errors=23) on origin/main (d8f7e20; 23 of the 28 tests error there) and pass here; 34 of 34 mutants of the change killed. The unit templates skill-invoke-rate.service and
.timer, which were never installed, are replaced by skill-invoke-rate-{claude,codex}.{service,timer}; installing them is the command center's act. Two line locators that the eight added lines of
skill_usage.py moved are updated, and the evidence rows are written again.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
… measured limits, and run it from the live clone

CPA-C-002 of the Claude-family practice audit (claude-practice-audit-claude-20261012, finding G3-01) and the command center's ruling of 2026-10-12: the per-skill invoke record of #970 was not running, and
would not have run as templated. Three things failed, each measured on the host:

- The /skill-doctor capture hit the 30 s default of skill_usage.py (it takes about 19 s on a quiet host and about 60 s at three runnable threads per CPU) and the daily run had no way to give it more. The
  default is now 300 s (DEFAULT_CLAUDE_TIMEOUT) and the daily run takes --claude-timeout.
- The run exited 2 unless `git branch --show-current` printed `main`, and the clone the unit renders for, ~/code/native-agent-stack-live, is a detached worktree of origin/main
  (docs/decisions/2026-10-09-claude-review-worker.md). The test is now "HEAD is a commit of origin/main" (`git merge-base --is-ancestor HEAD origin/main`, git-merge-base.adoc at git/git@67ad42147a), for
  the collection and for --render-units alike: a feature branch, a commit of the clone's own and a clone with no origin/main are refused with a fixed message.
- One run held the Claude and the Codex scans behind one exit status: as a transient user unit it took 23 min 57 s and exited 1, because the Codex lanes scan alone takes 25 min 47 s. The daily run is now two
  halves, `--half claude` (the /skill-doctor capture and the Claude lanes sweep) and `--half codex` (the host report's Codex scan and the lanes report), each its own user unit with its own record
  (skill-invoke-rate-claude-latest.json, skill-invoke-rate-codex-latest.json), `measured` holding only its own keys and the exit status standing for them. After its record, a half refreshes the combined
  skill-invoke-rate-latest.json that the Fleet page reads, merged from its own record and the other half's newest (the older of the two stamps, a missing or foreign record is an absent half). A slow Codex scan
  can no longer leave the Claude half unmeasured, and a timeout marks only its own half.

Limits per command, from transient-unit measurements on the host: the capture 19.9 s (limit 360 s with its margin), the Claude lanes sweep 2 min 18 s (600 s), the host report's Codex scan 1 min 10 s (600 s), the
Codex lanes scan 25 min 47 s (3,120 s, twice its wall, the command center's rule). TimeoutStartSec of each unit exceeds the sum of its half's limits by a minute (17 min and 63 min; a test pins it;
oneshot units have no start timeout unless one is set: systemd/systemd@e846bbad04 man/systemd.service.xml L682-L689). The units run at 09:30 and 10:00 UTC (OnCalendar with the literal UTC timezone,
man/systemd.time.xml L254-L256), inside the quietest span of the host's load by hour (08:00 to 13:00 UTC).

End to end, rendered from a detached worktree of origin/main and run as transient units: the Claude half 2 min 43.9 s (exit 0, host and claude measured), the Codex half 28 min 3.6 s (exit 0, codex measured), the
combined record measured for all three keys, mode 0600.

Fail-first: the 28 tests of tests.test_skill_usage_daily give FAILED (errors=23) on origin/main (d8f7e20; 23 of the 28 tests error there) and pass here; 34 of 34 mutants of the change killed. The unit templates skill-invoke-rate.service and
.timer, which were never installed, are replaced by skill-invoke-rate-{claude,codex}.{service,timer}; installing them is the command center's act. Two line locators that the eight added lines of
skill_usage.py moved are updated, and the evidence rows are written again.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 13, 2026
… measured limits, and run it from the live clone

CPA-C-002 of the Claude-family practice audit (claude-practice-audit-claude-20261012, finding G3-01) and the command center's ruling of 2026-10-12: the per-skill invoke record of #970 was not running, and
would not have run as templated. Three things failed, each measured on the host:

- The /skill-doctor capture hit the 30 s default of skill_usage.py (it takes about 19 s on a quiet host and about 60 s at three runnable threads per CPU) and the daily run had no way to give it more. The
  default is now 300 s (DEFAULT_CLAUDE_TIMEOUT) and the daily run takes --claude-timeout.
- The run exited 2 unless `git branch --show-current` printed `main`, and the clone the unit renders for, ~/code/native-agent-stack-live, is a detached worktree of origin/main
  (docs/decisions/2026-10-09-claude-review-worker.md). The test is now "HEAD is a commit of origin/main" (`git merge-base --is-ancestor HEAD origin/main`, git-merge-base.adoc at git/git@67ad42147a), for
  the collection and for --render-units alike: a feature branch, a commit of the clone's own and a clone with no origin/main are refused with a fixed message.
- One run held the Claude and the Codex scans behind one exit status: as a transient user unit it took 23 min 57 s and exited 1, because the Codex lanes scan alone takes 25 min 47 s. The daily run is now two
  halves, `--half claude` (the /skill-doctor capture and the Claude lanes sweep) and `--half codex` (the host report's Codex scan and the lanes report), each its own user unit with its own record
  (skill-invoke-rate-claude-latest.json, skill-invoke-rate-codex-latest.json), `measured` holding only its own keys and the exit status standing for them. After its record, a half refreshes the combined
  skill-invoke-rate-latest.json that the Fleet page reads, merged from its own record and the other half's newest (the older of the two stamps, a missing or foreign record is an absent half). A slow Codex scan
  can no longer leave the Claude half unmeasured, and a timeout marks only its own half.

Limits per command, from transient-unit measurements on the host: the capture 19.9 s (limit 360 s with its margin), the Claude lanes sweep 2 min 18 s (600 s), the host report's Codex scan 1 min 10 s (600 s), the
Codex lanes scan 25 min 47 s (3,120 s, twice its wall, the command center's rule). TimeoutStartSec of each unit exceeds the sum of its half's limits by a minute (17 min and 63 min; a test pins it;
oneshot units have no start timeout unless one is set: systemd/systemd@e846bbad04 man/systemd.service.xml L682-L689). The units run at 09:30 and 10:00 UTC (OnCalendar with the literal UTC timezone,
man/systemd.time.xml L254-L256), inside the quietest span of the host's load by hour (08:00 to 13:00 UTC).

End to end, rendered from a detached worktree of origin/main and run as transient units: the Claude half 2 min 43.9 s (exit 0, host and claude measured), the Codex half 28 min 3.6 s (exit 0, codex measured), the
combined record measured for all three keys, mode 0600.

Fail-first: the 28 tests of tests.test_skill_usage_daily give FAILED (errors=23) on origin/main (d8f7e20; 23 of the 28 tests error there) and pass here; 34 of 34 mutants of the change killed. The unit templates skill-invoke-rate.service and
.timer, which were never installed, are replaced by skill-invoke-rate-{claude,codex}.{service,timer}; installing them is the command center's act. Two line locators that the eight added lines of
skill_usage.py moved are updated, and the evidence rows are written again.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 14, 2026
… measured limits, and run it from the live clone

CPA-C-002 of the Claude-family practice audit (claude-practice-audit-claude-20261012, finding G3-01) and the command center's ruling of 2026-10-12: the per-skill invoke record of #970 was not running, and
would not have run as templated. Three things failed, each measured on the host:

- The /skill-doctor capture hit the 30 s default of skill_usage.py (it takes about 19 s on a quiet host and about 60 s at three runnable threads per CPU) and the daily run had no way to give it more. The
  default is now 300 s (DEFAULT_CLAUDE_TIMEOUT) and the daily run takes --claude-timeout.
- The run exited 2 unless `git branch --show-current` printed `main`, and the clone the unit renders for, ~/code/native-agent-stack-live, is a detached worktree of origin/main
  (docs/decisions/2026-10-09-claude-review-worker.md). The test is now "HEAD is a commit of origin/main" (`git merge-base --is-ancestor HEAD origin/main`, git-merge-base.adoc at git/git@67ad42147a), for
  the collection and for --render-units alike: a feature branch, a commit of the clone's own and a clone with no origin/main are refused with a fixed message.
- One run held the Claude and the Codex scans behind one exit status: as a transient user unit it took 23 min 57 s and exited 1, because the Codex lanes scan alone takes 25 min 47 s. The daily run is now two
  halves, `--half claude` (the /skill-doctor capture and the Claude lanes sweep) and `--half codex` (the host report's Codex scan and the lanes report), each its own user unit with its own record
  (skill-invoke-rate-claude-latest.json, skill-invoke-rate-codex-latest.json), `measured` holding only its own keys and the exit status standing for them. After its record, a half refreshes the combined
  skill-invoke-rate-latest.json that the Fleet page reads, merged from its own record and the other half's newest (the older of the two stamps, a missing or foreign record is an absent half). A slow Codex scan
  can no longer leave the Claude half unmeasured, and a timeout marks only its own half.

Limits per command, from transient-unit measurements on the host: the capture 19.9 s (limit 360 s with its margin), the Claude lanes sweep 2 min 18 s (600 s), the host report's Codex scan 1 min 10 s (600 s), the
Codex lanes scan 25 min 47 s (3,120 s, twice its wall, the command center's rule). TimeoutStartSec of each unit exceeds the sum of its half's limits by a minute (17 min and 63 min; a test pins it;
oneshot units have no start timeout unless one is set: systemd/systemd@e846bbad04 man/systemd.service.xml L682-L689). The units run at 09:30 and 10:00 UTC (OnCalendar with the literal UTC timezone,
man/systemd.time.xml L254-L256), inside the quietest span of the host's load by hour (08:00 to 13:00 UTC).

End to end, rendered from a detached worktree of origin/main and run as transient units: the Claude half 2 min 43.9 s (exit 0, host and claude measured), the Codex half 28 min 3.6 s (exit 0, codex measured), the
combined record measured for all three keys, mode 0600.

Fail-first: the 28 tests of tests.test_skill_usage_daily give FAILED (errors=23) on origin/main (d8f7e20; 23 of the 28 tests error there) and pass here; 34 of 34 mutants of the change killed. The unit templates skill-invoke-rate.service and
.timer, which were never installed, are replaced by skill-invoke-rate-{claude,codex}.{service,timer}; installing them is the command center's act. Two line locators that the eight added lines of
skill_usage.py moved are updated, and the evidence rows are written again.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
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