Skip to content

[docs] - Resync the knowledge and session skills and make the privacy verify script check something - #1645

Merged
cgfixit merged 2 commits into
mainfrom
claude/skills-knowledge-sync
Oct 13, 2026
Merged

cgfixit merged 2 commits into
mainfrom
claude/skills-knowledge-sync

Conversation

@cgfixit

@cgfixit cgfixit commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Proposed changes

Skill-catalog resync, part 3 of 3 (#1642 covers the loop/persona skills; #1643, the checker skills, is merged; all three touch disjoint files). This one covers fable-protocol (and its references/knowledge-base.md), cyclaw-gotchas, cyclaw-privacy and CyClaw-Sandbox, plus their sibling scripts and the two thin command wrappers.

  • fable-protocol / knowledge-base. The §8.4 block restated CLAUDE.md's invariants, load-bearing numbers, traps and git workflow, and four of the copies had rotted: max_context_tokens 8000 (config: 16000), chunk 512/50 (256/32), a num_ctx floor of 13,596 with the env file "at 16384" (now 21,596 and 32768), and a harness package in the I6 list that [infra] - Remove the Python coding-harness console; CG-agent-harness owns that role #1367 removed. Those blocks are replaced by pointers to CLAUDE.md §2–§5/§10 plus the two or three facts worth knowing cold. Also: the audit log is keyed HMAC-SHA256 fingerprinting, not plain SHA-256; "CLAUDE.md §5 asks for conventional commits" is false (the hook enforces [prefix] - sentence on every commit); "/index/build not API-key gated" now says "while the key is unset"; the chromadb CVE acceptance lives in SECURITY.md; python-coding-agent (no such skill) is gone from the trajectory note; the 65-line consolidation + version history is a dated 15-line list; SKILL.md §5.4 says soul.md is governed (I5), not immutable, matching the knowledge base's own words; the Opus 4.8→5→5.5 bracket is one sentence.
  • cyclaw-gotchas. Two gotchas expired under the file's own rule (dated strike): the --ignore-installed PyYAML trap (every install is now the hashed locks/ from [infra] - Park hashed pip locks in locks/ and drop temp paths from comments #1598; tests/test_macos_scripts.py asserts the old constraints rewrite is gone) and the [fix] - guard POST /api/agent/run with the harness's existing generation gate #1247 Codex P2 made moot by [infra] - Remove the Python coding-harness console; CG-agent-harness owns that role #1367. "Bare python3 is 3.11 and always will be" is false on the current image (3.13); the venv step describes the uv path the driver actually takes; checks runs six guards, not five (dotenv-guard was added; driver.sh's header fixed too); the test section follows CLAUDE.md §5 instead of "then the whole suite once"; advisory count 5→4 chromadb; doc_sync.py coverage is D1–D13.
  • cyclaw-privacy. Heading no longer says CyClaw-Advisor; the audit bullet names query_fingerprint (keyed HMAC, key env/file is itself a data element) and the include_query_hash: false regression; episodes use query_fingerprint, not hash_query; the data map gains logs/cyclaw.log (with the third_party_level DEBUG key-leak caveat from config.yaml) and logs/evals/eval_runs.jsonl. verify.sh used to print "Dep files consistent (from previous analysis)" without checking anything; it now reads config.yaml and asserts the posture SKILL.md cites (fingerprinted audit, redaction on, sk-ant shape present, no off-box context by default, memory/auth off, third-party log level above DEBUG), exit 0/2, clean SKIP without PyYAML. bootstrap.sh prints the SHA to cite and runs it.
  • CyClaw-Sandbox. Reconciled against main @ 663a8bb: "six ladders" → five; the Guardrails table is 22 rows with historical gaps, not "26-row"/"N/26"; I6 names the core six everywhere (and the sequence_detect grep covers gate*.py); the gate-routes row adds the console-session routes and says gate_runtime_check.py pins a subset; the console row has 7 panels and 3 JS files; /index/build is key-gated once CYCLAW_API_KEY is set (which Step 5 sets); only run_full_verification.py auto-detects the realism tier; test_terminal_consoles.py and verify.sh are described by what they run; smoke.sh's suite is section F; Known residual 4 reflects the Users/Audit UI auth_admin.js already provides; steps are numbered 1–9 without a gap; Step 2's requirements.txt --ignore-installed PyYAML recipe is replaced by driver.sh venv / §8; the memory-orchestrator history paragraph and the mock-embedding internals are trimmed to pointers.
  • Sandbox scripts. run_full_verification.py Phase 6 grepped gate.py for ANTHROPIC_API_KEY, sk-ant- and GROK_API_KEY — none has been there since redaction moved to utils/logger.py (redact_sensitive, _MINIMUM_SECRET_PATTERNS) and utils/public_errors.py, so three checks failed on every run; the phase now checks the real home and exercises public_error. test-specifications.md R1–R3 and its YAML snippet had the same stale targets and the wrong config path (logging.audit → policy.privacy); verify.sh's header claimed nine stages (it has seven; the SKILL.md table was already right); .claude/commands/CyClaw-Sandbox.md claimed the skill opens a draft PR and tests a "harness console" (CLAUDE.md §9: opens no PR; the harness is gone).
  • Trim pass (33912e8, at the owner's request): fable-protocol §8.2/§9 no longer restate §1/§6/§1.5/§2.6 inside the same file and the knowledge base no longer repeats §5.1's CWE-1022 note; cyclaw-gotchas' human-run section and Guardrails are one paragraph each; CyClaw-Sandbox loses two Gotchas that restated Step 2 and the operator map, Known residual 1 is six lines, and Guardrails rows 1–5 (CLAUDE.md §3 verbatim) are one row pointing at invariant-guard — the skill-specific rows 7–26 are unchanged.

Net: 364 insertions, 443 deletions across 12 files.

Invariant / Governance Impact: none of the six invariants or I6 changes; nothing outside .claude/ is touched. The pre-commit gate flagged the agent-instruction surface (every change is in the diff) and asked two secure-by-design questions about run_full_verification.py:958-969: those lines read utils/logger.py/utils/public_errors.py source text and run public_error on a fake sk-ant-api03-… string — no new config input, no new telemetry, and the fake key is asserted absent from the output.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Security (auth, privacy, injection, egress, redaction, or secrets)
  • Invariant / Governance refinement (use this for changes that strengthen or evolve the 6 invariants, I6 isolation, or harness phases)
  • Dependencies (added, removed, or bumped)
  • CI / infrastructure (workflows, hooks, templates, or checkers)
  • Refactor or tests (behavior-preserving, no new capability)
  • Documentation update
  • Other (none of the boxes above fit)

Scope note: Docs + audits, plus skill-local verify/bootstrap scripts and the Sandbox swarm's Phase 6.

Benefits / why

  • The knowledge base is what a Sonnet-tier session gets injected on /fable-protocol; it was teaching four wrong numbers and a dead package name. Pointing at CLAUDE.md means doc-sync D3/D8 now guard those facts instead of a prose copy nobody checked.
  • cyclaw-privacy/verify.sh is classified stdlib in ci.yml's verify-skills matrix; it now actually verifies the posture a privacy review cites, so a config change that turns include_query_hash off or routes context off-box fails that leg.
  • The Sandbox swarm's Phase 6 cannot have passed since the redaction code moved; it can now.

Risks to monitor

  • cyclaw-privacy/verify.sh reads config.yaml keys by name; a rename of policy.privacy.* or logging.audit.include_query_hash will fail it loudly (exit 2), which is the intent, but the message names the key so the fix is obvious.
  • run_full_verification.py's new Phase 6 could not be executed in the authoring sandbox (no torch/fastapi; the proxy denies the model host); it was syntax-checked and its targets grepped by hand, and CI's verify-skills (CyClaw-Sandbox) leg is green on 33912e8. .claude/skills/CyClaw-Sandbox/verify.sh is the blocking lifecycle and does not call Phase 6.
  • The fable-protocol description still names "Sonnet 5.5 vs Opus 5.5" while the body routes on "Sonnet 5"; the model-naming calibration is the owner's and was left alone.

Checklist

  • I have read docs/THREAT_MODEL.md, INVARIANTS.md and SECURITY.md (and any relevant Phase docs)
  • This change preserves all 6 security invariants and I6 module isolation (no core file touched)
  • Full sandbox validation has been run — not run locally; per CLAUDE.md §5 the suites ran in GitHub Actions and every leg is green on 33912e8. Run directly: cyclaw-privacy/verify.sh and bootstrap.sh (both pass, exit 0), cyclaw-gotchas/verify.sh (OK, re-run after the trim), doc_sync.py (0 drift), py_compile + bash -n on every edited script, ruff on run_full_verification.py (the 7 findings predate this branch, same count on main).
  • No new external network dependencies or mandatory online LLM assumptions were introduced
  • For any agentic/fsconnect change — n/a
  • Relevant architecture docs or threat model notes have been updated if core behavior or topology changed — n/a
  • Commit messages follow the title prefix convention above
  • For large or complex changes: before/after invariant matrix — n/a

Further comments

Measured across the three PRs, the 23 SKILL.md files plus the fable knowledge base go from 5,340 to 4,971 lines, a 6.9% trim (the first pass landed at 2.1%; the owner asked for the rest, which came from duplicated CLAUDE.md content, boilerplate repeated across the four loops, and dated history — never from a rule stated only once). Left for the owner: whether §8.2–8.3 of fable-protocol (the communication contract and "the pattern") belong only in the user-level copy per PROJECT_RULES.md's PII rule — they carry no DOB/email/location, so they were left as is.

Suggested merge order of open PRs

Trial merges verified (git merge --no-commit --no-ff + abort) against main @ 659d910 on 2026-10-13 (after #1637, #1638, #1640 and #1643 merged). This PR and #1642 touch disjoint files under .claude/; neither overlaps the other open PRs.

#1641 · Safe ✅
Impact: CI bwrap/AppArmor workflow; independent.
Action: merge anytime.

#1642 · Safe ✅
Impact: loop/persona skill files; disjoint from this PR.
Action: merge anytime.

#1644 · Safe ✅
Impact: CI bwrap/AppArmor selection; independent of this PR.
Action: merge anytime.

#1645 (this PR) · Safe ✅
Impact: fable-protocol, cyclaw-gotchas, cyclaw-privacy, CyClaw-Sandbox files only.
Action: merge anytime; re-run the trial merge if main moves.

#1646 · Safe ✅
Impact: otel-hardening inventory; independent of this PR.
Action: merge anytime.

ELI5

Four of the repo's "what to know" sheets for AI sessions had memorised an older version of the project: wrong context-window and chunk numbers, a package that was deleted months ago, an install recipe that no longer exists, and a privacy "verifier" that printed "all good" without looking at anything. One sandbox self-test had also been failing quietly for a while because it searched the wrong file for the secret-redaction code. This PR makes the sheets point at the single source of truth (CLAUDE.md and config.yaml) instead of copying it, turns the privacy verifier into a real check of nine config settings, points the self-test at where the redaction code lives now, and cuts the paragraphs that said the same thing twice. Nothing in the running server changes. What could still go wrong: if someone renames one of those nine config keys, the privacy verifier goes red with the key name in its message; the sandbox self-test's new checks ran green in CI's advisory verify-skills leg, and the first full run_full_verification.py on a real venv is the remaining proof.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LbrgG4NUbR3sUTgNMfKXpU


Generated by Claude Code

Last updated: 2026-10-13 04:46 ET

… verify script check something

fable-protocol's knowledge base restated CLAUDE.md's invariants, numbers,
traps and git workflow and had drifted on four of them (max_context_tokens
8000 vs 16000, chunk 512/50 vs 256/32, a num_ctx floor of 13,596 vs the
current 21,596, and a `harness` package in the I6 list that #1367 removed);
those blocks now point at CLAUDE.md §2-§5/§10 and keep only what must be
known cold. Its version history is condensed to a dated list, the audit log
is described as keyed HMAC-SHA256 fingerprinting (not plain SHA-256), and
the "/index/build is not key-gated" decision row says "while the key is
unset". cyclaw-gotchas expires two gotchas under its own rule (the
`--ignore-installed PyYAML` trap retired by the hashed locks in #1598, and
the #1247 Codex P2 made moot by #1367), counts six stdlib guards, aligns its
test guidance with CLAUDE.md §5, and stops asserting bare python3 is 3.11.
cyclaw-privacy's heading loses the old cyclaw-advisor name, its audit and
memory bullets name query_fingerprint and the HMAC key file, the data map
gains logs/cyclaw.log and the eval ledger, and verify.sh now checks the
shipped privacy posture in config.yaml (fingerprinted audit, redaction on,
no off-box context, memory/auth off, third-party log level above DEBUG)
instead of echoing "consistent (from previous analysis)"; bootstrap.sh
runs it. CyClaw-Sandbox is reconciled against main @ 663a8bb: five ladders
not six, the Guardrails table's historical numbering, the core six in every
I6 statement, the console's third JS file and seven panels, /index/build's
key gate once CYCLAW_API_KEY is set, the realism-tier auto-detection that
only run_full_verification.py performs, the real coverage of
test_terminal_consoles.py and gate_runtime_check.py, the auth UI that
auth_admin.js already provides, contiguous step numbers, and the
driver.sh/locks install in place of the retired requirements.txt recipe.
run_full_verification.py's Phase 6 and test-specifications.md R1-R3 grepped
gate.py for a redaction tuple that moved to utils/logger.py and
utils/public_errors.py, so three checks failed on every run; they now read
the real home and call public_error. verify.sh's header claimed nine stages
(it has seven), and the /CyClaw-Sandbox wrapper claimed the skill opens a
draft PR (CLAUDE.md §9: it opens none).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbrgG4NUbR3sUTgNMfKXpU
… and duplicated rows

fable-protocol's §8.2 and §9 restated §1/§6/§1.5/§2.6 inside the same file
and the knowledge base repeated §5.1's CWE-1022 note; cyclaw-gotchas' human-run
section and Guardrails restated the Run section and CLAUDE.md; CyClaw-Sandbox's
first two Gotchas restated Step 2 and the operator map, Known residual 1 ran
to ten lines, and Guardrails rows 1-5 restated CLAUDE.md §3 (collapsed to one
row pointing at invariant-guard; the skill-specific rows 7-26 are unchanged).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbrgG4NUbR3sUTgNMfKXpU
@cgfixit
cgfixit marked this pull request as ready for review October 13, 2026 09:52
@cgfixit
cgfixit merged commit 6902d39 into main Oct 13, 2026
61 of 62 checks passed
@cgfixit
cgfixit deleted the claude/skills-knowledge-sync branch October 13, 2026 09:52
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 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-13T10:03:06.432612Z 33912e8 Draft marked ready
ℹ️ 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.

cgfixit added a commit that referenced this pull request Oct 13, 2026
…-13)

High-signal since 3fe8217 (#1619): #1637 telemetry/egress inventory completion (fail-closed kill block, full spawn-site table for PowerShell/pip/brew/git-remote cat-3, agent-tooling boundary, OLLAMA_HOST pin, secret-env wrappers); #1643/#1645 docs resyncs correcting I6/harness and checker skill drifts. Graph remains 12 nodes.

@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: 33912e822e

ℹ️ 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 on lines +29 to +30
("logging.audit.include_query_hash", get("logging.audit.include_query_hash", True) is True,
"audit stream stores keyed HMAC fingerprints, never raw query text"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Read include_query_hash from audit_fields

When the shipped privacy toggle is changed to logging.audit_fields.include_query_hash: false, this lookup still returns its True default because it queries the nonexistent logging.audit.include_query_hash path. The verifier therefore reports the privacy posture as healthy even though audit_log starts persisting redacted raw queries; use the actual audit_fields path or the production include_query_hash helper. The same incorrect key is also published in the updated privacy skill.

AGENTS.md reference: AGENTS.md:L5-L7

Useful? React with 👍 / 👎.

Comment on lines +17 to +19
except ImportError:
print("SKIP: PyYAML not importable (fresh container); nothing checked")
sys.exit(0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not pass when PyYAML is unavailable

In the repository's verify-skills workflow, cyclaw-privacy is assigned the stdlib profile, which installs no PyYAML, so this branch is taken on every CI run and exits successfully after checking nothing. That makes the newly added posture verifier appear green in its primary automated environment; either classify the skill under the YAML profile or return a non-success skip status rather than treating missing prerequisites as verification.

AGENTS.md reference: AGENTS.md:L44-L49

Useful? React with 👍 / 👎.

Comment on lines +413 to 415
policy:
privacy:
redact_secrets_like:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep privacy under the existing policy mapping

This example now declares the top-level policy key twice. PyYAML silently keeps only the second mapping, so parsing or copying the documented hybrid configuration drops the entire fallback block immediately above it; strict YAML parsers may reject it outright. Nest privacy alongside fallback under the first policy mapping so the test specification represents the actual config.yaml structure.

AGENTS.md reference: AGENTS.md:L5-L7

Useful? React with 👍 / 👎.

Comment on lines +964 to +966
has_env_scan = "os.environ.items()" in logger_src and "def redact_sensitive" in logger_src
log(f" [{'PASS' if has_env_scan else 'FAIL'}] redact_sensitive scans every os.environ value (Grok + Anthropic parity)")
phase.checks.append(Check("env_value_redaction", has_env_scan))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Test the secret-name filter instead of any env iteration

This check and its PASS message claim that every environment value is redacted, but redact_sensitive only replaces values whose names match SECRET_POLICY and whose values are at least eight characters. Merely finding os.environ.items() therefore passes even if provider names stop being classified, and arbitrary environment values demonstrably remain unchanged; exercise the classification/redaction behavior directly or narrow the advertised guarantee.

AGENTS.md reference: AGENTS.md:L33-L33

Useful? React with 👍 / 👎.

Comment on lines +41 to +42
("logging.third_party_level", str(get("logging.third_party_level", "INFO")).upper() != "DEBUG",
"third-party log level above DEBUG (httpcore DEBUG writes Authorization headers)"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject NOTSET as an unsafe third-party log level

When logging.third_party_level is set to NOTSET, this predicate passes because the value is not the literal string DEBUG, but production resolves it to logging level 0 and admits DEBUG records, including the httpcore Authorization-header output this check is intended to prevent. Validate that the resolved logging level is at least INFO, rather than checking inequality with one spelling.

AGENTS.md reference: AGENTS.md:L33-L33

Useful? React with 👍 / 👎.

Comment on lines +158 to +161
- ~~**`--ignore-installed PyYAML` reinstalls everything, not just PyYAML**~~
— expired 2026-10-13: every documented install now uses the hashed
`locks/` with `--require-hashes` (#1598), no install line carries
`--ignore-installed`, and `tests/test_macos_scripts.py` asserts the old

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the PyYAML reinstall warning active

The claim that no documented install still uses --ignore-installed is contradicted by the active docs/! How-To-Guides/OLLAMA_SETUP.md command, which still runs pip install -r requirements.txt -c constraints.txt --ignore-installed PyYAML. Marking this gotcha expired hides the resolver/torch-floating risk from users following that guide; update the remaining guide to the hashed-lock flow before retiring the warning.

AGENTS.md reference: AGENTS.md:L35-L37

Useful? React with 👍 / 👎.

Comment on lines +32 to +35
**The six invariants and the load-bearing numbers** live in `CLAUDE.md` §3
and §2 ("Load-bearing numbers"), which `doc-sync` D3/D8 keep honest; this
file stopped carrying its own copy on 2026-10-13 after the copy drifted
(`max_context_tokens`, chunk sizes and the `num_ctx` floor were all a

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not claim D3 and D8 cover all invariants and numbers

doc-sync D3 checks only five numeric keys (api.port, retrieval.min_score, retrieval.rrf_k, api.graph_timeout_sec, and personality.soul_max_chars), while D8 checks only the graph node count; neither validates the six security invariants, max_context_tokens, chunk sizes, or the num_ctx floor cited here. This statement gives agents false confidence that the authoritative copy cannot drift, so name the narrower coverage and point invariant/context claims to their actual checkers.

AGENTS.md reference: AGENTS.md:L5-L7

Useful? React with 👍 / 👎.

| Auth routes | `gate_auth.py` | 13 paths (`/auth/setup-status`, `/bootstrap-password`, `/login`, `/logout`, `/whoami`, `/users` GET+POST, `/password`, `/users/{u}/password`, `/users/{u}/role`, `/users/{u}/disable`, `/users/{u}/enable`, `/users/{u}` DELETE, `/audit/summary`); every route exists and answers **503** (not 404) when `auth.enabled` is false (the shipped default); identity attaches to `POST /query` only when an `AuthManager` exists; `audit` role is forbidden from `/query`; account lockout answers **423**; a raced duplicate username or device-token label is a typed conflict (`AuthUserExists`/`AuthTokenLabelExists` -> **409**) | `test_auth_admin_contract.py`, `tests/test_due_diligence_invariants.py` |
| Memory routes | `gate_memory.py` | `/memory/status` is always 200 (probeable when the subsystem is off); `/memory/{facts,episodes,proposals,propose,apply,reject}` and `/query/export/html` are **404** when their toggle is off (all ship false); flag resolution goes through `memory/flags.py` -- the fact-retrieval switch is `memory.facts.retrieval_enabled` (legacy `memory.facts.enabled` honored with a one-time warning), the status payload reports `facts_retrieval_enabled`, and every flag echo is a strict boolean (`is True` -- a YAML `"false"` string reports off) | `test_memory_isolation.py`-style isolation + live probe |
| Terminal console | `static/terminal.html` + `static/terminal.js` (CSP forces `script-src 'self'`, so the console's JS logic lives in the sibling file -- read both together) | 5 toolbar panels (Soul/Sync/Agentic/FS/SQL); the confirm dialog's generic `handleConfirm(confirmed, entryId, onlineProvider)`; the four slash commands `/users /admin /audit /help` (everything else is a toolbar button or a RAG query, not a command) | `tests/test_terminal_contract.py` (reads `terminal.html + terminal.js` combined; pins the 5 POST-only paths) |
| Terminal console | `static/terminal.html` + `static/terminal.js` + `static/auth_admin.js` (CSP forces `script-src 'self'`, so the console's JS logic lives in the sibling files -- read all three together) | 7 toolbar panels (Soul/Sync/Agentic/FS/SQL, plus Users and Audit, which stay hidden until `auth.enabled`); the confirm dialog's generic `handleConfirm(confirmed, entryId, onlineProvider)`; the four slash commands `/users /admin /audit /help` (everything else is a toolbar button or a RAG query, not a command) | `tests/test_terminal_contract.py` (reads the HTML and JS combined; its `_POST_PATHS` pins every POST-only path -- derive the count from the file, it grows) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Include auth_admin.js in the route contract

This row says the terminal contract reads all three browser assets and that _POST_PATHS pins every POST-only path, but tests/test_terminal_contract.py::_console_source concatenates only terminal.html and terminal.js. Consequently the Users panel's dynamic POST /auth/users, role, password-reset, and delete calls in auth_admin.js are not checked against gateway routes or HTTP methods, so those endpoints can drift while the advertised contract remains green; include the third asset and account for its dynamically constructed paths.

Useful? React with 👍 / 👎.

Comment on lines +218 to +220
even with auth off; `/index/build` is loopback+same-origin gated and, once
`CYCLAW_API_KEY` is set (as it is in this step), also key-gated -- it is
deliberately NOT key-gated while the key is unset so a first-run build cannot

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Export the generated session key before live probes

On a fresh shell, Step 2 merely prints a generated key and never assigns it to CYCLAW_API_KEY, yet the live-gate command later expands that variable and this changed text claims it is set. Following the procedure therefore starts the server with an empty key—or aborts under set -u—and the authenticated soul/ops console probes cannot exercise the documented path; assign and export the generated value before launching the server.

AGENTS.md reference: AGENTS.md:L20-L22

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants