coding-os 0.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adapters/claude/README.md +6 -0
- adapters/claude/_install_helpers/extract_stacks.py +43 -0
- adapters/claude/_install_helpers/update_mcp_json.py +75 -0
- adapters/claude/adapter.yaml +164 -0
- adapters/claude/hooks/README.md +40 -0
- adapters/claude/hooks/agent_memory_sync.py +131 -0
- adapters/claude/hooks/ensure-agent-memory-link.sh +36 -0
- adapters/claude/hooks/sync-agent-memory.sh +21 -0
- adapters/claude/install.sh +86 -0
- adapters/claude/sdk_dispatcher.py +871 -0
- adapters/claude/settings.local.template.json +31 -0
- adapters/claude/settings.template.json +808 -0
- adapters/claude/update_mcp_json.py +85 -0
- adapters/codex/adapter.yaml +254 -0
- adapters/codex/chat_provider.py +230 -0
- adapters/codex/commands/formula-f1.md +129 -0
- adapters/codex/commands/formula-f10.md +100 -0
- adapters/codex/commands/formula-f11.md +123 -0
- adapters/codex/commands/formula-f2.md +139 -0
- adapters/codex/commands/formula-f3.md +127 -0
- adapters/codex/commands/formula-f4.md +101 -0
- adapters/codex/commands/formula-f5.md +135 -0
- adapters/codex/commands/formula-f6.md +147 -0
- adapters/codex/commands/formula-f7.md +111 -0
- adapters/codex/commands/formula-f8.md +133 -0
- adapters/codex/commands/formula-f9.md +112 -0
- adapters/codex/enable_codex_hooks.py +94 -0
- adapters/codex/ensure_codex_mcp.py +124 -0
- adapters/codex/hooks/codex-merge-hook-output.py +72 -0
- adapters/codex/hooks/codex-normalize-edit.py +96 -0
- adapters/codex/hooks/codex-postedit-dispatch.sh +75 -0
- adapters/codex/hooks/codex-posttool-dispatch.sh +70 -0
- adapters/codex/hooks/codex-preedit-dispatch.sh +83 -0
- adapters/codex/hooks/codex-pretool-dispatch.sh +82 -0
- adapters/codex/hooks/codex-sessionend-dispatch.sh +20 -0
- adapters/codex/hooks/codex-sessionstart-dispatch.sh +68 -0
- adapters/codex/hooks/codex-stop-dispatch.sh +73 -0
- adapters/codex/hooks/codex-userpromptsubmit-dispatch.sh +74 -0
- adapters/codex/hooks.template.json +208 -0
- adapters/codex/install.sh +83 -0
- adapters/codex/sdk_dispatcher.py +449 -0
- board_os/__init__.py +39 -0
- board_os/_agent_runtime.py +256 -0
- board_os/config.py +421 -0
- board_os/git_coherence.py +107 -0
- board_os/hub_adapter_manifest.py +140 -0
- board_os/mcp_tools.py +3228 -0
- board_os/migration.py +166 -0
- board_os/parser.py +317 -0
- board_os/presence.py +156 -0
- board_os/sync.py +320 -0
- board_os/transition_gates.py +224 -0
- board_os/transition_gates_cli.py +272 -0
- board_os/transition_gates_validator.py +551 -0
- board_os/verify_suites.py +126 -0
- board_os/verify_suites_cli.py +328 -0
- board_os/workflow.py +967 -0
- cli/__init__.py +0 -0
- cli/_data_types.py +248 -0
- cli/_init_helpers.py +587 -0
- cli/_resources.py +100 -0
- cli/adapter_registry.py +239 -0
- cli/add_stack.py +315 -0
- cli/aggregator.py +438 -0
- cli/board_commands.py +1218 -0
- cli/brain_commands.py +255 -0
- cli/cognition.py +345 -0
- cli/config_composer.py +349 -0
- cli/core_version.py +41 -0
- cli/cron_commands.py +278 -0
- cli/db_reset.py +298 -0
- cli/doc_commands.py +111 -0
- cli/doctor.py +2953 -0
- cli/doctor_board.py +365 -0
- cli/doctor_extras.py +1121 -0
- cli/doctor_graph.py +608 -0
- cli/doctor_tokens.py +254 -0
- cli/graph_commands.py +1265 -0
- cli/hook_renderer.py +393 -0
- cli/hub_commands.py +580 -0
- cli/list_adapters.py +79 -0
- cli/list_stacks.py +105 -0
- cli/logs_commands.py +89 -0
- cli/main.py +3070 -0
- cli/materialize_file.py +65 -0
- cli/mcp_start.py +153 -0
- cli/module_commands.py +513 -0
- cli/pr_commands.py +2024 -0
- cli/preset_commands.py +126 -0
- cli/preset_registry.py +171 -0
- cli/project_overrides.py +119 -0
- cli/registry.py +365 -0
- cli/remove_stack.py +492 -0
- cli/renderer.py +620 -0
- cli/setup.py +464 -0
- cli/skill_commands.py +689 -0
- cli/skill_registry.py +235 -0
- cli/skills_list.py +332 -0
- cli/stack_lint.py +351 -0
- cli/stack_registry.py +688 -0
- cli/subsystems.py +335 -0
- cli/sync_all.py +310 -0
- cli/tail_command.py +410 -0
- cli/update.py +608 -0
- cli/verify_since_edit.py +439 -0
- coding_os-0.3.2.dist-info/METADATA +508 -0
- coding_os-0.3.2.dist-info/RECORD +1304 -0
- coding_os-0.3.2.dist-info/WHEEL +5 -0
- coding_os-0.3.2.dist-info/entry_points.txt +5 -0
- coding_os-0.3.2.dist-info/licenses/LICENSE +201 -0
- coding_os-0.3.2.dist-info/top_level.txt +10 -0
- core/__init__.py +0 -0
- core/board_os/__init__.py +39 -0
- core/board_os/_agent_runtime.py +256 -0
- core/board_os/config.py +421 -0
- core/board_os/git_coherence.py +107 -0
- core/board_os/hub_adapter_manifest.py +140 -0
- core/board_os/mcp_tools.py +3228 -0
- core/board_os/migration.py +166 -0
- core/board_os/parser.py +317 -0
- core/board_os/presence.py +156 -0
- core/board_os/sync.py +320 -0
- core/board_os/transition-gates.yaml +176 -0
- core/board_os/transition_gates.py +224 -0
- core/board_os/transition_gates_cli.py +272 -0
- core/board_os/transition_gates_validator.py +551 -0
- core/board_os/verify-suites.yaml +113 -0
- core/board_os/verify_suites.py +126 -0
- core/board_os/verify_suites_cli.py +328 -0
- core/board_os/workflow.py +967 -0
- core/commands/board.md +27 -0
- core/commands/classify.md +23 -0
- core/commands/compose.md +23 -0
- core/commands/daily.md +31 -0
- core/commands/diagnose.md +7 -0
- core/commands/memory-search.md +23 -0
- core/commands/new-project.md +33 -0
- core/commands/retro.md +38 -0
- core/commands/review.md +14 -0
- core/commands/task.md +17 -0
- core/commands/verify.md +34 -0
- core/docs/thinking_os-final-edition.md +1449 -0
- core/doctor-config.yaml +74 -0
- core/graph_os/__init__.py +29 -0
- core/graph_os/backend.py +233 -0
- core/graph_os/backends/__init__.py +13 -0
- core/graph_os/backends/sqlite_backend.py +1053 -0
- core/graph_os/bench/__init__.py +17 -0
- core/graph_os/bench/fixtures.py +56 -0
- core/graph_os/bench/harness.py +95 -0
- core/graph_os/bench/persian_precision.py +142 -0
- core/graph_os/bench/scale_500k.py +120 -0
- core/graph_os/bench/token_cost.py +170 -0
- core/graph_os/bench/viewer_fps.py +110 -0
- core/graph_os/communities.py +410 -0
- core/graph_os/enterprise.py +218 -0
- core/graph_os/entry_points.py +226 -0
- core/graph_os/extractors/__init__.py +25 -0
- core/graph_os/extractors/code_generic.py +914 -0
- core/graph_os/extractors/code_go.py +1422 -0
- core/graph_os/extractors/code_json.py +340 -0
- core/graph_os/extractors/code_php.py +979 -0
- core/graph_os/extractors/code_python.py +1454 -0
- core/graph_os/extractors/code_shell.py +538 -0
- core/graph_os/extractors/code_toml.py +302 -0
- core/graph_os/extractors/code_ts.py +1665 -0
- core/graph_os/extractors/code_yaml.py +394 -0
- core/graph_os/extractors/contracts.py +1592 -0
- core/graph_os/extractors/md_links.py +890 -0
- core/graph_os/extractors/task_deps.py +345 -0
- core/graph_os/groups/__init__.py +22 -0
- core/graph_os/groups/cross_repo.py +156 -0
- core/graph_os/groups/manifest.py +141 -0
- core/graph_os/ingest/__init__.py +19 -0
- core/graph_os/ingest/base.py +306 -0
- core/graph_os/ingest/github.py +112 -0
- core/graph_os/ingest/zip.py +95 -0
- core/graph_os/toolchain.py +393 -0
- core/graph_os/tools/__init__.py +9 -0
- core/graph_os/tools/graph.py +5573 -0
- core/graph_os/tools/reindex_dispatch.py +730 -0
- core/graph_os/tree_sitter_overlay.py +235 -0
- core/graph_os/types.py +252 -0
- core/graph_os/vec_index.py +277 -0
- core/graph_os/viewer/__init__.py +12 -0
- core/graph_os/viewer/exporter.py +93 -0
- core/graph_os/viewer/template.py +189 -0
- core/hooks/_helpers/_paths.py +40 -0
- core/hooks/_helpers/advance_role.py +72 -0
- core/hooks/_helpers/auto_compose.py +228 -0
- core/hooks/_helpers/auto_validate_lessons.py +55 -0
- core/hooks/_helpers/branch_guard_check.py +796 -0
- core/hooks/_helpers/check_commit_message.py +108 -0
- core/hooks/_helpers/check_dangerous_rm.py +80 -0
- core/hooks/_helpers/check_git_bypass.py +154 -0
- core/hooks/_helpers/check_git_destructive.py +77 -0
- core/hooks/_helpers/check_settings_write.py +97 -0
- core/hooks/_helpers/consume_override.py +51 -0
- core/hooks/_helpers/context_budget.py +77 -0
- core/hooks/_helpers/cos_say_json.py +103 -0
- core/hooks/_helpers/destructive_edit_check.py +163 -0
- core/hooks/_helpers/detect_status_transition.py +82 -0
- core/hooks/_helpers/digest_regen.py +56 -0
- core/hooks/_helpers/doc_sync_check.py +498 -0
- core/hooks/_helpers/drain_embedding_outbox.py +52 -0
- core/hooks/_helpers/extract_additional_context.py +51 -0
- core/hooks/_helpers/extract_commit_msg_arg.py +74 -0
- core/hooks/_helpers/git_command_parse.py +424 -0
- core/hooks/_helpers/git_settings_fields.py +47 -0
- core/hooks/_helpers/graph_context_match.py +37 -0
- core/hooks/_helpers/graph_marker_check.py +70 -0
- core/hooks/_helpers/jit_recall.py +56 -0
- core/hooks/_helpers/json_field.py +41 -0
- core/hooks/_helpers/narrative_signal.py +59 -0
- core/hooks/_helpers/observation_count.py +31 -0
- core/hooks/_helpers/pre_commit_batch.py +177 -0
- core/hooks/_helpers/pre_commit_fake_input.py +42 -0
- core/hooks/_helpers/presence_gc.py +102 -0
- core/hooks/_helpers/presence_write.py +167 -0
- core/hooks/_helpers/recover_indirect.py +35 -0
- core/hooks/_helpers/routing_evolution.py +104 -0
- core/hooks/_helpers/session_recap.py +72 -0
- core/hooks/_helpers/skill_primer.py +229 -0
- core/hooks/_helpers/task_sync.py +59 -0
- core/hooks/_helpers/tool_failure_capture.py +147 -0
- core/hooks/_helpers/trajectory_autosnap.py +278 -0
- core/hooks/_helpers/trajectory_startup.py +62 -0
- core/hooks/_helpers/turn_summary.py +82 -0
- core/hooks/_helpers/validate_task_frontmatter.py +98 -0
- core/hooks/_helpers/wip_limit_check.py +103 -0
- core/hooks/_helpers/wip_lines.py +53 -0
- core/hooks/_helpers/work_log_append.py +89 -0
- core/hooks/_helpers/wrap_dispatch_output.py +82 -0
- core/hooks/advance-role.sh +48 -0
- core/hooks/agent-presence.sh +179 -0
- core/hooks/auto-brain-decay.sh +184 -0
- core/hooks/auto-compose-roles.sh +83 -0
- core/hooks/auto-graph-reconcile-shell.sh +119 -0
- core/hooks/auto-regen-doc-index.sh +120 -0
- core/hooks/auto-reindex-docs.sh +130 -0
- core/hooks/auto-task-sync.sh +56 -0
- core/hooks/auto-trace-rotate.sh +88 -0
- core/hooks/block-bad-patterns.sh +212 -0
- core/hooks/block-dangerous-commands.sh +182 -0
- core/hooks/block-hardcoded-literals.sh +90 -0
- core/hooks/block-migration-conflict.sh +114 -0
- core/hooks/block-protected-files.sh +129 -0
- core/hooks/block-secrets.sh +185 -0
- core/hooks/block-shared-tree-edit.sh +75 -0
- core/hooks/block-uv-heredoc.sh +78 -0
- core/hooks/branch-guard.sh +122 -0
- core/hooks/capture-observation.sh +76 -0
- core/hooks/capture-tool-failure.sh +24 -0
- core/hooks/capture-work-log.sh +89 -0
- core/hooks/check-agents-md-refs.sh +75 -0
- core/hooks/check-agents-md-size.sh +49 -0
- core/hooks/check-capture-worked.sh +148 -0
- core/hooks/check-doc-size.sh +61 -0
- core/hooks/check-mcp-extras.sh +92 -0
- core/hooks/check-state.sh +87 -0
- core/hooks/classify-task-mode.sh +103 -0
- core/hooks/cos-env.sh +1301 -0
- core/hooks/drain-embedding-outbox.sh +24 -0
- core/hooks/enforce-anti-ambiguity.sh +74 -0
- core/hooks/enforce-commit-message.sh +73 -0
- core/hooks/enforce-doc-anchor.sh +224 -0
- core/hooks/enforce-doc-sync.sh +206 -0
- core/hooks/enforce-graph-context.sh +89 -0
- core/hooks/enforce-graph-first-read.sh +94 -0
- core/hooks/enforce-memory-check.sh +128 -0
- core/hooks/enforce-rename-plan.sh +78 -0
- core/hooks/enforce-scaffold-boundary.sh +68 -0
- core/hooks/enforce-skill.sh +125 -0
- core/hooks/enforce-task-body.sh +52 -0
- core/hooks/enforce-task-start.sh +81 -0
- core/hooks/enforce-task-transition.sh +75 -0
- core/hooks/enforce-template.sh +143 -0
- core/hooks/enforce-verify.sh +112 -0
- core/hooks/enforce-wip-limit.sh +43 -0
- core/hooks/enforce-zoom.sh +69 -0
- core/hooks/ensure-hub-up.sh +67 -0
- core/hooks/inject-mcp-caller-session.sh +70 -0
- core/hooks/jit-recall.sh +65 -0
- core/hooks/link-commit-to-task.sh +143 -0
- core/hooks/lint-task.sh +40 -0
- core/hooks/nudge-docs-first.sh +71 -0
- core/hooks/nudge-git-mode.sh +29 -0
- core/hooks/nudge-graph-os.sh +118 -0
- core/hooks/nudge-learn-narrative.sh +36 -0
- core/hooks/nudge-model-routing.sh +32 -0
- core/hooks/nudge-reentry.sh +101 -0
- core/hooks/nudge-reuse-first.sh +68 -0
- core/hooks/nudge-task-discovery.sh +81 -0
- core/hooks/nudge-thinking-os.sh +109 -0
- core/hooks/pr-reap.sh +23 -0
- core/hooks/reclaim-sweep.sh +58 -0
- core/hooks/record-verify-auto.sh +77 -0
- core/hooks/record-verify.sh +74 -0
- core/hooks/regen-reminder.sh +104 -0
- core/hooks/registry.yaml +1262 -0
- core/hooks/remind-daily.sh +27 -0
- core/hooks/remind-dogfood.sh +70 -0
- core/hooks/remind-learn-validate.sh +94 -0
- core/hooks/rules-primer.sh +50 -0
- core/hooks/search-enforce-inventory.sh +108 -0
- core/hooks/search-verify-remaining.sh +132 -0
- core/hooks/session-context.sh +729 -0
- core/hooks/session-end.sh +145 -0
- core/hooks/session-skill-primer.sh +43 -0
- core/hooks/snapshot-transcript.sh +56 -0
- core/hooks/sync-task-current.sh +85 -0
- core/hooks/test-first-reminder.sh +120 -0
- core/hooks/test-governor.sh +173 -0
- core/hooks/thinking_os-gate.sh +52 -0
- core/hooks/track-backtrack.sh +35 -0
- core/hooks/track-discovery.sh +121 -0
- core/hooks/track-skill.sh +53 -0
- core/hooks/validate-task-frontmatter.sh +49 -0
- core/hooks/verify-rename-callers.sh +119 -0
- core/hooks/warn-abandoned-task.sh +99 -0
- core/hooks/warn-destructive-edit.sh +64 -0
- core/hooks/warn-diff-size.sh +43 -0
- core/hooks/warn-graph-empty.sh +81 -0
- core/hooks/warn-mcp-down.sh +190 -0
- core/hooks/write-state.sh +55 -0
- core/logging_os/__init__.py +33 -0
- core/logging_os/api.py +127 -0
- core/logging_os/bridge.py +80 -0
- core/logging_os/config.py +172 -0
- core/logging_os/fingerprint.py +25 -0
- core/logging_os/redact.py +53 -0
- core/logging_os/render.py +83 -0
- core/logging_os/sinks.py +164 -0
- core/rules/anti-overengineering.md +44 -0
- core/rules/api-contract-discipline.md +41 -0
- core/rules/dimension-registry.md +155 -0
- core/rules/git-workflow.md +57 -0
- core/rules/memory.md +46 -0
- core/rules/model-routing.md +22 -0
- core/rules/skill-enforcement.md +75 -0
- core/rules/test-discipline.md +38 -0
- core/rules/thinking_os.md +48 -0
- core/rules/transparency-banner.md +37 -0
- core/runtime_paths.yaml +36 -0
- core/scaffold_manifest.json +14430 -0
- core/scheduled/__init__.py +0 -0
- core/scheduled/_activity.py +126 -0
- core/scheduled/_state.py +113 -0
- core/scheduled/config.py +86 -0
- core/scheduled/dep_reconcile.py +135 -0
- core/scheduled/error_sweep.py +137 -0
- core/scheduled/nightly.py +930 -0
- core/scheduled/responsive_extract.py +65 -0
- core/schemas/adapter.schema.json +269 -0
- core/schemas/preset.schema.json +50 -0
- core/schemas/skill.schema.json +81 -0
- core/schemas/stack.schema.json +404 -0
- core/scripts/_lib.sh +9 -0
- core/scripts/docs-lint.sh +228 -0
- core/scripts/docs-nav-fix.sh +133 -0
- core/scripts/docs-staleness-check.sh +154 -0
- core/scripts/install-adapter.sh +266 -0
- core/scripts/link-stack-skills.sh +52 -0
- core/scripts/log-latest.sh +106 -0
- core/scripts/log-search.sh +89 -0
- core/scripts/log-write.sh +134 -0
- core/scripts/ref-resolve.sh +71 -0
- core/skills/a11y/SKILL.md +305 -0
- core/skills/a11y/assets/a11y-checklist.md +137 -0
- core/skills/a11y/references/aria-and-focus.md +247 -0
- core/skills/a11y/references/rn-accessibility.md +343 -0
- core/skills/a11y/references/screen-reader-testing.md +190 -0
- core/skills/agent-memory/SKILL.md +191 -0
- core/skills/agent-memory/assets/memory-checklist.md +21 -0
- core/skills/agent-memory/references/memory-recipes.md +57 -0
- core/skills/api-design/SKILL.md +232 -0
- core/skills/api-design/assets/api-design-checklist.md +110 -0
- core/skills/api-design/references/error-envelope.md +381 -0
- core/skills/api-design/references/idempotency-pagination.md +312 -0
- core/skills/api-design/references/rest-contracts.md +426 -0
- core/skills/auth-patterns/SKILL.md +352 -0
- core/skills/auth-patterns/assets/auth-checklist.md +118 -0
- core/skills/auth-patterns/references/jwt-and-service-tokens.md +343 -0
- core/skills/auth-patterns/references/passkeys-2fa.md +289 -0
- core/skills/auth-patterns/references/sessions-vs-jwt.md +230 -0
- core/skills/auth-patterns/scripts/cookie-flag-check.py +146 -0
- core/skills/backend-fundamentals/SKILL.md +238 -0
- core/skills/backend-fundamentals/assets/backend-checklist.md +27 -0
- core/skills/backend-fundamentals/references/backend-patterns.md +56 -0
- core/skills/backend-fundamentals/scripts/check_layering.py +83 -0
- core/skills/clean-code/SKILL.md +642 -0
- core/skills/clean-code/scripts/audit-fail-closed.py +167 -0
- core/skills/codebase-explorer/SKILL.md +89 -0
- core/skills/codebase-explorer/assets/reading-checklist.md +24 -0
- core/skills/codebase-explorer/references/reading-strategies.md +52 -0
- core/skills/codebase-explorer/scripts/outline.py +99 -0
- core/skills/db-design/SKILL.md +327 -0
- core/skills/db-design/assets/migration-template.sql +49 -0
- core/skills/db-design/references/migration-discipline.md +290 -0
- core/skills/db-design/references/postgres-patterns.md +340 -0
- core/skills/db-design/scripts/migration-safety.sh +150 -0
- core/skills/deployment-cicd/SKILL.md +260 -0
- core/skills/deployment-cicd/assets/deploy-checklist.md +26 -0
- core/skills/deployment-cicd/references/pipeline-and-release.md +54 -0
- core/skills/deployment-cicd/scripts/lint_workflow.py +79 -0
- core/skills/docker/SKILL.md +114 -0
- core/skills/docker/assets/dockerfile-checklist.md +31 -0
- core/skills/docker/references/compose-patterns.md +66 -0
- core/skills/docker/references/dockerfile-optimization.md +64 -0
- core/skills/docker/scripts/lint_dockerfile.sh +48 -0
- core/skills/docker/versions.json +16 -0
- core/skills/end-to-end-testing/SKILL.md +101 -0
- core/skills/end-to-end-testing/assets/e2e-checklist.md +23 -0
- core/skills/end-to-end-testing/references/maestro.md +63 -0
- core/skills/end-to-end-testing/references/playwright.md +68 -0
- core/skills/end-to-end-testing/scripts/lint_e2e.py +88 -0
- core/skills/end-to-end-testing/versions.json +16 -0
- core/skills/frontend-design/SKILL.md +76 -0
- core/skills/frontend-design/assets/design-checklist.md +29 -0
- core/skills/frontend-design/references/design-principles.md +65 -0
- core/skills/frontend-design/scripts/check_contrast.py +89 -0
- core/skills/frontend-fundamentals/SKILL.md +213 -0
- core/skills/frontend-fundamentals/assets/frontend-checklist.md +25 -0
- core/skills/frontend-fundamentals/references/rendering-and-state.md +66 -0
- core/skills/frontend-fundamentals/scripts/check_frontend.py +86 -0
- core/skills/graph-explorer/SKILL.md +215 -0
- core/skills/graph-explorer/scripts/explain-impact.sh +64 -0
- core/skills/graphql/SKILL.md +187 -0
- core/skills/grpc-microservices/SKILL.md +174 -0
- core/skills/hexagonal-architecture/SKILL.md +199 -0
- core/skills/hexagonal-architecture/assets/folder-scaffold.md +233 -0
- core/skills/hexagonal-architecture/references/anti-patterns.md +129 -0
- core/skills/hexagonal-architecture/references/go-fiber-layout.md +429 -0
- core/skills/hexagonal-architecture/references/python-fastapi-layout.md +453 -0
- core/skills/hexagonal-architecture/references/react-native-layout.md +428 -0
- core/skills/i18n/SKILL.md +126 -0
- core/skills/incident-response/SKILL.md +225 -0
- core/skills/incident-response/assets/incident-checklist.md +29 -0
- core/skills/incident-response/references/severity-and-runbook.md +53 -0
- core/skills/incident-response/scripts/classify_severity.py +86 -0
- core/skills/linux-sysadmin/SKILL.md +115 -0
- core/skills/linux-sysadmin/assets/hardening-checklist.md +29 -0
- core/skills/linux-sysadmin/references/ssh-hardening.md +62 -0
- core/skills/linux-sysadmin/references/systemd-and-services.md +77 -0
- core/skills/linux-sysadmin/scripts/triage.sh +50 -0
- core/skills/linux-sysadmin/versions.json +17 -0
- core/skills/llm-patterns/SKILL.md +410 -0
- core/skills/llm-patterns/assets/llm-feature-checklist.md +26 -0
- core/skills/llm-patterns/references/rag-and-evals.md +59 -0
- core/skills/llm-patterns/scripts/estimate_tokens.py +75 -0
- core/skills/messaging-queues/SKILL.md +142 -0
- core/skills/mobile-fundamentals/SKILL.md +406 -0
- core/skills/mobile-fundamentals/assets/mobile-launch-checklist.md +130 -0
- core/skills/mobile-fundamentals/references/navigation-and-deep-links.md +337 -0
- core/skills/mobile-fundamentals/references/offline-sync.md +339 -0
- core/skills/node-backend/SKILL.md +114 -0
- core/skills/node-backend/assets/node-checklist.md +25 -0
- core/skills/node-backend/references/async-and-errors.md +67 -0
- core/skills/node-backend/references/event-loop.md +65 -0
- core/skills/node-backend/scripts/check_package.py +78 -0
- core/skills/node-backend/versions.json +17 -0
- core/skills/observability/SKILL.md +289 -0
- core/skills/observability/assets/observability-checklist.md +27 -0
- core/skills/observability/references/instrumentation.md +57 -0
- core/skills/observability/scripts/lint_logging.py +77 -0
- core/skills/payments/SKILL.md +102 -0
- core/skills/performance/SKILL.md +305 -0
- core/skills/performance/assets/perf-checklist.md +143 -0
- core/skills/performance/references/mobile-performance.md +249 -0
- core/skills/performance/references/web-vitals.md +209 -0
- core/skills/php/SKILL.md +116 -0
- core/skills/php/assets/php-checklist.md +26 -0
- core/skills/php/references/modern-php.md +64 -0
- core/skills/php/references/security.md +72 -0
- core/skills/php/scripts/scan_php_smells.py +99 -0
- core/skills/php/versions.json +9 -0
- core/skills/pr-mode-driver/SKILL.md +65 -0
- core/skills/realtime-websockets/SKILL.md +152 -0
- core/skills/redis/SKILL.md +105 -0
- core/skills/redis/assets/redis-checklist.md +27 -0
- core/skills/redis/references/operations.md +66 -0
- core/skills/redis/references/patterns.md +62 -0
- core/skills/redis/scripts/analyze_info.py +101 -0
- core/skills/redis/versions.json +9 -0
- core/skills/search/SKILL.md +91 -0
- core/skills/search/references/grep.md +76 -0
- core/skills/search/scripts/verify-count.sh +73 -0
- core/skills/search-infra/SKILL.md +109 -0
- core/skills/security-mobile/SKILL.md +394 -0
- core/skills/security-mobile/assets/mobile-security-checklist.md +117 -0
- core/skills/security-mobile/references/masvs-l1-checklist.md +127 -0
- core/skills/security-web/SKILL.md +217 -0
- core/skills/security-web/assets/security-web-checklist.md +167 -0
- core/skills/security-web/references/owasp-top-10.md +551 -0
- core/skills/security-web/references/supply-chain.md +179 -0
- core/skills/security-web/scripts/csp-check.sh +153 -0
- core/skills/shell-scripting/SKILL.md +128 -0
- core/skills/shell-scripting/assets/script-checklist.md +33 -0
- core/skills/shell-scripting/references/argument-parsing.md +84 -0
- core/skills/shell-scripting/references/bash-robustness.md +78 -0
- core/skills/shell-scripting/scripts/lint_script.sh +53 -0
- core/skills/shell-scripting/scripts/new_script.py +131 -0
- core/skills/shell-scripting/versions.json +23 -0
- core/skills/sql-authoring/SKILL.md +104 -0
- core/skills/sql-authoring/assets/query-review-checklist.md +26 -0
- core/skills/sql-authoring/references/query-patterns.md +89 -0
- core/skills/sql-authoring/references/reading-explain.md +52 -0
- core/skills/sql-authoring/scripts/analyze_plan.py +100 -0
- core/skills/sql-authoring/versions.json +17 -0
- core/skills/state-management/SKILL.md +428 -0
- core/skills/state-management/references/tanstack-query-recipes.md +301 -0
- core/skills/state-management/references/zustand-recipes.md +364 -0
- core/skills/supabase/SKILL.md +108 -0
- core/skills/supabase/assets/supabase-checklist.md +26 -0
- core/skills/supabase/references/realtime-and-storage.md +55 -0
- core/skills/supabase/references/rls-and-auth.md +65 -0
- core/skills/supabase/scripts/check_rls.py +88 -0
- core/skills/supabase/versions.json +9 -0
- core/skills/task-driver/SKILL.md +272 -0
- core/skills/task-driver/scripts/task-lint.sh +163 -0
- core/skills/technical-writing/SKILL.md +85 -0
- core/skills/technical-writing/assets/doc-checklist.md +29 -0
- core/skills/technical-writing/references/doc-anatomy.md +53 -0
- core/skills/technical-writing/references/writing-craft.md +59 -0
- core/skills/technical-writing/scripts/new_doc.py +81 -0
- core/skills/terraform-k8s/SKILL.md +133 -0
- core/skills/testing-strategy/SKILL.md +266 -0
- core/skills/testing-strategy/assets/test-review-checklist.md +25 -0
- core/skills/testing-strategy/references/test-types.md +52 -0
- core/skills/testing-strategy/scripts/coverage_gate.py +79 -0
- core/skills/thinking_os/SKILL.md +288 -0
- core/skills/thinking_os/scripts/classify.sh +122 -0
- core/skills/typescript/SKILL.md +110 -0
- core/skills/typescript/assets/typescript-checklist.md +24 -0
- core/skills/typescript/references/strictness.md +53 -0
- core/skills/typescript/references/type-system.md +86 -0
- core/skills/typescript/scripts/check_tsconfig.py +92 -0
- core/skills/typescript/versions.json +9 -0
- core/subsystems.yaml +202 -0
- core/thinking_os/__init__.py +1 -0
- core/thinking_os/_agent_markers.py +32 -0
- core/thinking_os/agents/README.md +71 -0
- core/thinking_os/agents/analyst.md +139 -0
- core/thinking_os/agents/architect.md +127 -0
- core/thinking_os/agents/debugger.md +111 -0
- core/thinking_os/agents/deployer.md +112 -0
- core/thinking_os/agents/distiller.md +28 -0
- core/thinking_os/agents/documenter.md +101 -0
- core/thinking_os/agents/implementer.md +135 -0
- core/thinking_os/agents/internal/session_observer.md +39 -0
- core/thinking_os/agents/observer.md +100 -0
- core/thinking_os/agents/onboarder.md +81 -0
- core/thinking_os/agents/refactorer.md +123 -0
- core/thinking_os/agents/repairer.md +47 -0
- core/thinking_os/agents/researcher.md +129 -0
- core/thinking_os/agents/reviewer.md +147 -0
- core/thinking_os/agents/security_auditor.md +133 -0
- core/thinking_os/background.py +405 -0
- core/thinking_os/bootstrap_outcomes.py +200 -0
- core/thinking_os/budget.py +302 -0
- core/thinking_os/capture.py +495 -0
- core/thinking_os/cognition.py +516 -0
- core/thinking_os/cognition_schemas.py +517 -0
- core/thinking_os/compress.py +192 -0
- core/thinking_os/concepts.py +233 -0
- core/thinking_os/dashboard.py +159 -0
- core/thinking_os/database.py +2883 -0
- core/thinking_os/decay.py +393 -0
- core/thinking_os/digest.py +295 -0
- core/thinking_os/dispatcher.py +192 -0
- core/thinking_os/dispatcher_helpers.py +48 -0
- core/thinking_os/dispatchers/__init__.py +3 -0
- core/thinking_os/dispatchers/default.py +47 -0
- core/thinking_os/distill.py +192 -0
- core/thinking_os/doc_indexer.py +905 -0
- core/thinking_os/embeddings.py +943 -0
- core/thinking_os/formula_composer.py +556 -0
- core/thinking_os/gate_marker.py +75 -0
- core/thinking_os/graph.py +296 -0
- core/thinking_os/graph_indexer.py +360 -0
- core/thinking_os/health_check.py +517 -0
- core/thinking_os/impact.py +119 -0
- core/thinking_os/memory_gc.py +356 -0
- core/thinking_os/migrator_embeddings.py +318 -0
- core/thinking_os/precision.py +194 -0
- core/thinking_os/presets/registry.yaml +127 -0
- core/thinking_os/record_outcome.py +399 -0
- core/thinking_os/repair.py +105 -0
- core/thinking_os/retrieval_quality.py +239 -0
- core/thinking_os/roles/analyst.yaml +83 -0
- core/thinking_os/roles/architect.yaml +88 -0
- core/thinking_os/roles/debugger.yaml +71 -0
- core/thinking_os/roles/deployer.yaml +71 -0
- core/thinking_os/roles/documenter.yaml +72 -0
- core/thinking_os/roles/implementer.yaml +83 -0
- core/thinking_os/roles/observer.yaml +70 -0
- core/thinking_os/roles/refactorer.yaml +71 -0
- core/thinking_os/roles/researcher.yaml +72 -0
- core/thinking_os/roles/reviewer.yaml +79 -0
- core/thinking_os/roles/security_auditor.yaml +83 -0
- core/thinking_os/roles_state.py +168 -0
- core/thinking_os/sanitizer.py +320 -0
- core/thinking_os/server.py +3160 -0
- core/thinking_os/session_enrich.py +272 -0
- core/thinking_os/session_observe_worker.py +111 -0
- core/thinking_os/session_startup.py +74 -0
- core/thinking_os/session_summary.py +245 -0
- core/thinking_os/situations/registry.yaml +99 -0
- core/thinking_os/task_analyzer.py +462 -0
- core/thinking_os/task_parser.py +342 -0
- core/thinking_os/task_sync.py +73 -0
- core/thinking_os/tools/__init__.py +6 -0
- core/thinking_os/tools/_shared.py +947 -0
- core/thinking_os/tools/cognition.py +1867 -0
- core/thinking_os/tools/docs.py +770 -0
- core/thinking_os/tools/learning.py +2078 -0
- core/thinking_os/tools/logs.py +79 -0
- core/thinking_os/tools/memory.py +840 -0
- core/thinking_os/tools/metrics.py +200 -0
- core/thinking_os/tools/retrieve.py +415 -0
- core/thinking_os/tools/routing.py +658 -0
- core/thinking_os/tools/tasks.py +449 -0
- core/thinking_os/tools/trajectory.py +181 -0
- core/thinking_os/tracing.py +235 -0
- core/web/__init__.py +5 -0
- core/web/_cache.py +118 -0
- core/web/_deps.py +56 -0
- core/web/_envelope.py +85 -0
- core/web/_project_context.py +140 -0
- core/web/chat_providers.py +108 -0
- core/web/init_jobs.py +216 -0
- core/web/routes/__init__.py +25 -0
- core/web/routes/_bounded_read.py +76 -0
- core/web/routes/board.py +1089 -0
- core/web/routes/cognition.py +1838 -0
- core/web/routes/config.py +635 -0
- core/web/routes/graph.py +513 -0
- core/web/routes/health.py +180 -0
- core/web/routes/hooks.py +288 -0
- core/web/routes/hub.py +1219 -0
- core/web/routes/logs.py +374 -0
- core/web/routes/metrics.py +43 -0
- core/web/routes/observability.py +400 -0
- core/web/routes/patterns.py +227 -0
- core/web/routes/presence.py +609 -0
- core/web/routes/roles.py +446 -0
- core/web/routes/scheduled.py +261 -0
- core/web/routes/search.py +238 -0
- core/web/routes/sessions.py +220 -0
- core/web/routes/settings.py +363 -0
- core/web/routes/stream.py +547 -0
- core/web/security.py +157 -0
- core/web/server.py +283 -0
- graph_os/__init__.py +29 -0
- graph_os/backend.py +233 -0
- graph_os/backends/__init__.py +13 -0
- graph_os/backends/sqlite_backend.py +1053 -0
- graph_os/communities.py +410 -0
- graph_os/enterprise.py +218 -0
- graph_os/entry_points.py +226 -0
- graph_os/extractors/__init__.py +25 -0
- graph_os/extractors/code_generic.py +914 -0
- graph_os/extractors/code_go.py +1422 -0
- graph_os/extractors/code_json.py +340 -0
- graph_os/extractors/code_php.py +979 -0
- graph_os/extractors/code_python.py +1454 -0
- graph_os/extractors/code_shell.py +538 -0
- graph_os/extractors/code_toml.py +302 -0
- graph_os/extractors/code_ts.py +1665 -0
- graph_os/extractors/code_yaml.py +394 -0
- graph_os/extractors/contracts.py +1592 -0
- graph_os/extractors/md_links.py +890 -0
- graph_os/extractors/task_deps.py +345 -0
- graph_os/groups/__init__.py +22 -0
- graph_os/groups/cross_repo.py +156 -0
- graph_os/groups/manifest.py +141 -0
- graph_os/ingest/__init__.py +19 -0
- graph_os/ingest/base.py +306 -0
- graph_os/ingest/github.py +112 -0
- graph_os/ingest/zip.py +95 -0
- graph_os/toolchain.py +393 -0
- graph_os/tools/__init__.py +9 -0
- graph_os/tools/graph.py +5573 -0
- graph_os/tools/reindex_dispatch.py +730 -0
- graph_os/tree_sitter_overlay.py +235 -0
- graph_os/types.py +252 -0
- graph_os/vec_index.py +277 -0
- graph_os/viewer/__init__.py +12 -0
- graph_os/viewer/exporter.py +93 -0
- graph_os/viewer/template.py +189 -0
- scheduled/__init__.py +0 -0
- scheduled/_activity.py +126 -0
- scheduled/_state.py +113 -0
- scheduled/config.py +86 -0
- scheduled/dep_reconcile.py +135 -0
- scheduled/error_sweep.py +137 -0
- scheduled/nightly.py +930 -0
- scheduled/responsive_extract.py +65 -0
- scripts/__init__.py +4 -0
- scripts/_commit_msg_body.sh +31 -0
- scripts/_post_commit_body.sh +49 -0
- scripts/_pre_commit_body.sh +121 -0
- scripts/_prepare_commit_msg_body.sh +53 -0
- scripts/audit_mcp_tools.py +693 -0
- scripts/bench_sdk_dispatcher.py +177 -0
- scripts/capture_golden.py +169 -0
- scripts/check_graph_phantoms.py +75 -0
- scripts/dev/audit_doc_links.py +359 -0
- scripts/dev/audit_scaffold_module_tags.py +107 -0
- scripts/dev/backfill_doc_headers.py +328 -0
- scripts/dev/backfill_nav_lines.py +119 -0
- scripts/dev/fix_nav_placement.py +106 -0
- scripts/dev/inspect_sdk_options.py +45 -0
- scripts/dev/migrate_check_ids.py +170 -0
- scripts/dev/strip_purpose_blocks.py +154 -0
- scripts/dump_openapi.py +66 -0
- scripts/e2e_dispatch_tool.py +195 -0
- scripts/generate_manifest.py +166 -0
- scripts/golden_sections.py +20 -0
- scripts/graph_demo.py +161 -0
- scripts/install-git-hooks.sh +47 -0
- scripts/migrate_embeddings_minilm_to_bge_m3.py +84 -0
- scripts/operational_eval.py +445 -0
- scripts/probe_agent_session_resolver.py +59 -0
- scripts/prune_deleted_path.py +127 -0
- scripts/refactor_agent_dual_mode.py +171 -0
- scripts/refresh_skill_versions.py +302 -0
- scripts/regen_doc_index.py +209 -0
- scripts/regen_doctor_schema.py +62 -0
- scripts/regen_rules.py +94 -0
- scripts/rename_formulas_to_semantic.py +241 -0
- scripts/smoke_db_connections.py +183 -0
- scripts/smoke_doc_header.py +72 -0
- scripts/smoke_graph_e2e.py +374 -0
- scripts/smoke_sdk_dispatch.py +84 -0
- scripts/smoke_uid_resolver.py +164 -0
- scripts/verify_dispatchers.py +244 -0
- scripts/verify_phase_c_e2e.py +436 -0
- templates/__init__.py +6 -0
- templates/_base/Makefile.base +353 -0
- templates/_base/base.yaml +59 -0
- templates/_base/coding-os.yaml.template +39 -0
- templates/_base/dimension-registry.template.md +68 -0
- templates/_base/domain-config.template.json +46 -0
- templates/_base/fragments/anatomy-map.md.tmpl +11 -0
- templates/_base/fragments/context-discipline.md.tmpl +3 -0
- templates/_base/fragments/core-loop.md.tmpl +52 -0
- templates/_base/fragments/engineering-routing.md.tmpl +3 -0
- templates/_base/fragments/header.md.tmpl +6 -0
- templates/_base/fragments/identity.md.tmpl +3 -0
- templates/_base/fragments/principles.md.tmpl +3 -0
- templates/_base/fragments/retrieval-routing.md.tmpl +23 -0
- templates/_base/fragments/session-handoff.md.tmpl +3 -0
- templates/_base/fragments/skills.md.tmpl +3 -0
- templates/_base/fragments/ssot-map.md.tmpl +3 -0
- templates/_base/fragments/stop-conditions.md.tmpl +3 -0
- templates/_base/fragments/subagent-dispatch.md.tmpl +3 -0
- templates/_base/fragments/task-authoring.md.tmpl +69 -0
- templates/_base/fragments/task-logging.md.tmpl +8 -0
- templates/_base/fragments/tool-routing.md.tmpl +9 -0
- templates/_base/fragments/verification-matrix.md.tmpl +12 -0
- templates/_base/lang/dart/analysis_options.yaml +7 -0
- templates/_base/lang/php/phpcs.xml.dist +10 -0
- templates/_base/lang/python/pyproject.toml +19 -0
- templates/_base/lang/rust/clippy.toml +5 -0
- templates/_base/lang/rust/rustfmt.toml +3 -0
- templates/_base/lang/typescript/eslint.config.js +26 -0
- templates/_base/lang/typescript/tsconfig.json +15 -0
- templates/_base/lang/typescript/vitest.config.ts +10 -0
- templates/_base/scaffold/changes.log +1 -0
- templates/_base/scaffold/docs/00-index.md +55 -0
- templates/_base/scaffold/docs/_meta/feature-dependency-tree.md +30 -0
- templates/_base/scaffold/docs/_meta/foundation-map.md +56 -0
- templates/_base/scaffold/docs/_meta/questions.md +8 -0
- templates/_base/scaffold/docs/_meta/roadmap.md +33 -0
- templates/_base/scaffold/docs/api-contracts/00-index.md +58 -0
- templates/_base/scaffold/docs/api-contracts/error-format.md +58 -0
- templates/_base/scaffold/docs/architecture/00-index.md +42 -0
- templates/_base/scaffold/docs/architecture/adr/00-index.md +39 -0
- templates/_base/scaffold/docs/engineering/00-index.md +9 -0
- templates/_base/scaffold/docs/governance/00-index.md +55 -0
- templates/_base/scaffold/docs/governance/_templates/doc-cheat-sheet.md +202 -0
- templates/_base/scaffold/docs/governance/_templates/playbook-template.md +81 -0
- templates/_base/scaffold/docs/governance/_templates/post-mortem-template.md +85 -0
- templates/_base/scaffold/docs/governance/_templates/runbook-template.md +88 -0
- templates/_base/scaffold/docs/governance/_templates/security-review-template.md +111 -0
- templates/_base/scaffold/docs/governance/_templates/task-detail.md +61 -0
- templates/_base/scaffold/docs/governance/agent-workflow.md +101 -0
- templates/_base/scaffold/docs/governance/anatomy-contract.md +150 -0
- templates/_base/scaffold/docs/governance/critical-rules.md +224 -0
- templates/_base/scaffold/docs/governance/decision-records.md +58 -0
- templates/_base/scaffold/docs/governance/docs-first-protocol.md +157 -0
- templates/_base/scaffold/docs/governance/docs-system.md +151 -0
- templates/_base/scaffold/docs/governance/gdpr-compliance.md +66 -0
- templates/_base/scaffold/docs/governance/mcp-tool-inventory.md +112 -0
- templates/_base/scaffold/docs/governance/risk-register.md +26 -0
- templates/_base/scaffold/docs/governance/scaffold-boundary-contract.md +161 -0
- templates/_base/scaffold/docs/governance/task-lifecycle.md +125 -0
- templates/_base/scaffold/docs/governance/wrapper-derivation.md +50 -0
- templates/_base/scaffold/docs/insights/00-index.md +17 -0
- templates/_base/scaffold/docs/ops/00-index.md +59 -0
- templates/_base/scaffold/docs/ops/runbooks/00-index.md +9 -0
- templates/_base/scaffold/docs/playbooks/00-index.md +12 -0
- templates/_base/scaffold/docs/playbooks/research-validation.md +29 -0
- templates/_base/scaffold/docs/playbooks/security-review.md +41 -0
- templates/_base/scaffold/docs/prd/00-index.md +43 -0
- templates/_base/scaffold/docs/prd/01-snapshot-vision.md +56 -0
- templates/_base/scaffold/docs/workflow/workflow-guide.md +138 -0
- templates/_base/scaffold/src/shared/README.md +23 -0
- templates/_base/skill-enforcement.template.md +14 -0
- templates/_base/task-detail.template.md +61 -0
- templates/_presets/ai-saas.yaml +9 -0
- templates/_presets/django-next.yaml +8 -0
- templates/_presets/dotnet-react.yaml +8 -0
- templates/_presets/flutter-baas.yaml +8 -0
- templates/_presets/go-react.yaml +8 -0
- templates/_presets/hexagonal-product.yaml +16 -0
- templates/_presets/jamstack.yaml +8 -0
- templates/_presets/laravel-vue.yaml +8 -0
- templates/_presets/mean.yaml +8 -0
- templates/_presets/mern.yaml +9 -0
- templates/_presets/nest-angular.yaml +8 -0
- templates/_presets/nextjs-fastapi.yaml +10 -0
- templates/_presets/nuxt-fullstack.yaml +9 -0
- templates/_presets/pern.yaml +9 -0
- templates/_presets/rails-react.yaml +8 -0
- templates/_presets/rn-api.yaml +8 -0
- templates/_presets/rust-svelte.yaml +8 -0
- templates/_presets/spring-react.yaml +8 -0
- templates/_presets/t3-style.yaml +9 -0
- templates/_presets/tall.yaml +8 -0
- templates/_presets/wordpress-cms.yaml +8 -0
- templates/angular/rules/frontend.md +19 -0
- templates/angular/scaffold/docs/engineering/accessibility.md +46 -0
- templates/angular/scaffold/docs/engineering/angular-rules.md +35 -0
- templates/angular/scaffold/docs/playbooks/angular-app.md +42 -0
- templates/angular/scaffold/src/frontend/angular.json +52 -0
- templates/angular/scaffold/src/frontend/package.json +28 -0
- templates/angular/scaffold/src/frontend/src/app/app.component.ts +19 -0
- templates/angular/scaffold/src/frontend/src/app/app.config.ts +22 -0
- templates/angular/scaffold/src/frontend/src/app/app.routes.ts +8 -0
- templates/angular/scaffold/src/frontend/src/app/core/global-error-handler.ts +12 -0
- templates/angular/scaffold/src/frontend/src/app/health/health.component.ts +14 -0
- templates/angular/scaffold/src/frontend/src/app/health/health.service.spec.ts +16 -0
- templates/angular/scaffold/src/frontend/src/app/health/health.service.ts +10 -0
- templates/angular/scaffold/src/frontend/src/index.html +11 -0
- templates/angular/scaffold/src/frontend/src/main.ts +9 -0
- templates/angular/scaffold/src/frontend/src/styles.css +14 -0
- templates/angular/scaffold/src/frontend/tsconfig.app.json +8 -0
- templates/angular/scaffold/src/frontend/tsconfig.json +27 -0
- templates/angular/scaffold/src/frontend/tsconfig.spec.json +8 -0
- templates/angular/scaffold-boundary.yaml +27 -0
- templates/angular/skills/angular/SKILL.md +79 -0
- templates/angular/skills/angular/references/anatomy.md +69 -0
- templates/angular/stack.yaml +75 -0
- templates/aspnet-core/rules/backend.md +20 -0
- templates/aspnet-core/scaffold/docs/engineering/aspnet-core-rules.md +36 -0
- templates/aspnet-core/scaffold/docs/playbooks/aspnet-core-service.md +40 -0
- templates/aspnet-core/scaffold/src/backend/Backend.csproj +11 -0
- templates/aspnet-core/scaffold/src/backend/Backend.sln +27 -0
- templates/aspnet-core/scaffold/src/backend/Common/ExceptionHandlingMiddleware.cs +35 -0
- templates/aspnet-core/scaffold/src/backend/Features/Health/HealthEndpoints.cs +10 -0
- templates/aspnet-core/scaffold/src/backend/Features/Health/HealthService.cs +9 -0
- templates/aspnet-core/scaffold/src/backend/Program.cs +22 -0
- templates/aspnet-core/scaffold/src/backend/tests/Backend.Tests/Backend.Tests.csproj +22 -0
- templates/aspnet-core/scaffold/src/backend/tests/Backend.Tests/HealthServiceTests.cs +15 -0
- templates/aspnet-core/scaffold-boundary.yaml +24 -0
- templates/aspnet-core/skills/aspnet-core/SKILL.md +80 -0
- templates/aspnet-core/skills/aspnet-core/references/anatomy.md +65 -0
- templates/aspnet-core/stack.yaml +68 -0
- templates/astro/rules/frontend.md +20 -0
- templates/astro/scaffold/docs/engineering/astro-rules.md +40 -0
- templates/astro/scaffold/docs/playbooks/astro-app.md +57 -0
- templates/astro/scaffold/docs/playbooks/content-seo.md +37 -0
- templates/astro/scaffold/src/frontend/astro.config.mjs +10 -0
- templates/astro/scaffold/src/frontend/package.json +23 -0
- templates/astro/scaffold/src/frontend/src/components/Greeting.astro +13 -0
- templates/astro/scaffold/src/frontend/src/content/posts/hello.md +10 -0
- templates/astro/scaffold/src/frontend/src/content.config.ts +19 -0
- templates/astro/scaffold/src/frontend/src/lib/problem.test.ts +39 -0
- templates/astro/scaffold/src/frontend/src/lib/problem.ts +30 -0
- templates/astro/scaffold/src/frontend/src/pages/api/health.ts +13 -0
- templates/astro/scaffold/src/frontend/src/pages/index.astro +21 -0
- templates/astro/scaffold/src/frontend/tsconfig.json +9 -0
- templates/astro/scaffold/src/frontend/vitest.config.ts +10 -0
- templates/astro/scaffold-boundary.yaml +28 -0
- templates/astro/skills/astro/SKILL.md +71 -0
- templates/astro/skills/astro/references/anatomy.md +66 -0
- templates/astro/stack.yaml +75 -0
- templates/csharp-plain/scaffold/src/backend/Backend.csproj +12 -0
- templates/csharp-plain/scaffold/src/backend/Program.cs +1 -0
- templates/csharp-plain/scaffold-boundary.yaml +23 -0
- templates/csharp-plain/stack.yaml +50 -0
- templates/django/rules/backend.md +18 -0
- templates/django/scaffold/docs/engineering/anti-ambiguity.md +74 -0
- templates/django/scaffold/docs/engineering/backend-rules.md +133 -0
- templates/django/scaffold/docs/engineering/glossary.md +51 -0
- templates/django/scaffold/docs/engineering/logging-standards.md +107 -0
- templates/django/scaffold/docs/engineering/naming-conventions.md +68 -0
- templates/django/scaffold/docs/engineering/secrets-rotation-runbook.md +142 -0
- templates/django/scaffold/docs/playbooks/backend-api.md +119 -0
- templates/django/scaffold/src/backend/config/__init__.py +0 -0
- templates/django/scaffold/src/backend/config/settings.py +31 -0
- templates/django/scaffold/src/backend/config/urls.py +11 -0
- templates/django/scaffold/src/backend/config/wsgi.py +6 -0
- templates/django/scaffold/src/backend/manage.py +14 -0
- templates/django/scaffold/src/backend/pyproject.toml +37 -0
- templates/django/scaffold/src/backend/tests/test_health.py +4 -0
- templates/django/scaffold-boundary.yaml +25 -0
- templates/django/skills/python-django/SKILL.md +450 -0
- templates/django/skills/python-django/references/anatomy.md +117 -0
- templates/django/skills/python-django/scripts/new_endpoint.py +89 -0
- templates/django/stack.yaml +73 -0
- templates/fastapi/rules/backend.md +18 -0
- templates/fastapi/scaffold/docs/engineering/fastapi-rules.md +37 -0
- templates/fastapi/scaffold/docs/playbooks/fastapi-service.md +30 -0
- templates/fastapi/scaffold/src/backend/app/__init__.py +0 -0
- templates/fastapi/scaffold/src/backend/app/main.py +8 -0
- templates/fastapi/scaffold/src/backend/pyproject.toml +39 -0
- templates/fastapi/scaffold/src/backend/tests/test_health.py +11 -0
- templates/fastapi/scaffold-boundary.yaml +25 -0
- templates/fastapi/skills/python-fastapi/SKILL.md +75 -0
- templates/fastapi/skills/python-fastapi/references/anatomy.md +117 -0
- templates/fastapi/skills/python-fastapi/scripts/new_endpoint.py +101 -0
- templates/fastapi/stack.yaml +57 -0
- templates/flutter/rules/mobile.md +26 -0
- templates/flutter/scaffold/docs/engineering/flutter-rules.md +35 -0
- templates/flutter/scaffold/docs/playbooks/flutter-app.md +45 -0
- templates/flutter/scaffold/src/mobile/lib/core/error_mapper.dart +17 -0
- templates/flutter/scaffold/src/mobile/lib/core/router.dart +13 -0
- templates/flutter/scaffold/src/mobile/lib/main.dart +22 -0
- templates/flutter/scaffold/src/mobile/lib/screens/health_screen.dart +32 -0
- templates/flutter/scaffold/src/mobile/lib/services/health_service.dart +11 -0
- templates/flutter/scaffold/src/mobile/lib/state/health_provider.dart +13 -0
- templates/flutter/scaffold/src/mobile/pubspec.yaml +22 -0
- templates/flutter/scaffold/src/mobile/test/health_provider_test.dart +90 -0
- templates/flutter/scaffold-boundary.yaml +28 -0
- templates/flutter/skills/flutter/SKILL.md +76 -0
- templates/flutter/skills/flutter/references/anatomy.md +64 -0
- templates/flutter/stack.yaml +70 -0
- templates/go/rules/backend.md +19 -0
- templates/go/scaffold/docs/engineering/go-rules.md +45 -0
- templates/go/scaffold/docs/playbooks/go-service.md +30 -0
- templates/go/scaffold/src/backend/cmd/api/main.go +22 -0
- templates/go/scaffold/src/backend/cmd/api/main_test.go +20 -0
- templates/go/scaffold/src/backend/go.mod +3 -0
- templates/go/scaffold-boundary.yaml +25 -0
- templates/go/skills/go-patterns/SKILL.md +68 -0
- templates/go/skills/go-patterns/assets/go-checklist.md +29 -0
- templates/go/skills/go-patterns/references/anatomy.md +115 -0
- templates/go/skills/go-patterns/references/go-2026-idioms.md +92 -0
- templates/go/skills/go-patterns/scripts/new_endpoint.py +117 -0
- templates/go/skills/go-patterns/versions.json +16 -0
- templates/go/stack.yaml +54 -0
- templates/go-fiber/rules/backend.md +20 -0
- templates/go-fiber/scaffold/docs/engineering/fiber-rules.md +97 -0
- templates/go-fiber/scaffold/docs/playbooks/fiber-service.md +149 -0
- templates/go-fiber/scaffold/src/backend/cmd/api/main.go +21 -0
- templates/go-fiber/scaffold/src/backend/cmd/api/main_test.go +17 -0
- templates/go-fiber/scaffold/src/backend/go.mod +23 -0
- templates/go-fiber/scaffold/src/backend/go.sum +49 -0
- templates/go-fiber/scaffold-boundary.yaml +26 -0
- templates/go-fiber/skills/go-fiber/SKILL.md +203 -0
- templates/go-fiber/skills/go-fiber/assets/fiber-checklist.md +26 -0
- templates/go-fiber/skills/go-fiber/references/anatomy.md +116 -0
- templates/go-fiber/skills/go-fiber/references/fiber-v3-patterns.md +89 -0
- templates/go-fiber/skills/go-fiber/scripts/new_endpoint.py +107 -0
- templates/go-fiber/skills/go-fiber/versions.json +16 -0
- templates/go-fiber/stack.yaml +59 -0
- templates/go-plain/scaffold/src/backend/go.mod +3 -0
- templates/go-plain/scaffold/src/backend/main.go +7 -0
- templates/go-plain/scaffold-boundary.yaml +22 -0
- templates/go-plain/stack.yaml +51 -0
- templates/java-plain/scaffold/src/backend/mvnw +302 -0
- templates/java-plain/scaffold/src/backend/pom.xml +41 -0
- templates/java-plain/scaffold/src/backend/src/main/java/com/example/app/Main.java +10 -0
- templates/java-plain/scaffold-boundary.yaml +23 -0
- templates/java-plain/stack.yaml +51 -0
- templates/laravel/rules/backend.md +20 -0
- templates/laravel/scaffold/docs/engineering/laravel-rules.md +28 -0
- templates/laravel/scaffold/docs/playbooks/laravel-service.md +28 -0
- templates/laravel/scaffold/src/backend/app/Exceptions/Handler.php +27 -0
- templates/laravel/scaffold/src/backend/app/Http/Controllers/HealthController.php +15 -0
- templates/laravel/scaffold/src/backend/app/Support/HealthStatus.php +14 -0
- templates/laravel/scaffold/src/backend/composer.json +24 -0
- templates/laravel/scaffold/src/backend/phpunit.xml +10 -0
- templates/laravel/scaffold/src/backend/public/index.php +8 -0
- templates/laravel/scaffold/src/backend/routes/api.php +7 -0
- templates/laravel/scaffold/src/backend/tests/Unit/HealthStatusTest.php +16 -0
- templates/laravel/scaffold-boundary.yaml +23 -0
- templates/laravel/skills/laravel/SKILL.md +56 -0
- templates/laravel/skills/laravel/references/anatomy.md +65 -0
- templates/laravel/stack.yaml +66 -0
- templates/meta/rules/graph-first.md +27 -0
- templates/meta/rules/hook-author.md +19 -0
- templates/meta/rules/mcp-tool-author.md +18 -0
- templates/meta/rules/meta-engineering.md +17 -0
- templates/meta/scaffold-boundary.yaml +55 -0
- templates/meta/skills/claude-sdk-integration/SKILL.md +163 -0
- templates/meta/skills/claude-sdk-integration/assets/sdk-checklist.md +27 -0
- templates/meta/skills/claude-sdk-integration/scripts/check_model_ids.py +97 -0
- templates/meta/skills/graph-os-authoring/SKILL.md +278 -0
- templates/meta/skills/graph-os-authoring/assets/graph-os-checklist.md +25 -0
- templates/meta/skills/graph-os-authoring/scripts/new_extractor.py +76 -0
- templates/meta/skills/hook-authoring/SKILL.md +292 -0
- templates/meta/skills/hook-authoring/assets/hook-checklist.md +30 -0
- templates/meta/skills/hook-authoring/scripts/new_hook.sh +75 -0
- templates/meta/skills/mcp-tool-authoring/SKILL.md +301 -0
- templates/meta/skills/mcp-tool-authoring/assets/mcp-tool-checklist.md +29 -0
- templates/meta/skills/mcp-tool-authoring/scripts/new_tool.py +74 -0
- templates/meta/skills/meta-engineering/SKILL.md +151 -0
- templates/meta/skills/meta-engineering/assets/meta-edit-checklist.md +28 -0
- templates/meta/skills/meta-engineering/scripts/which_layer.py +61 -0
- templates/meta/skills/python-meta-server/SKILL.md +162 -0
- templates/meta/skills/python-meta-server/assets/meta-server-checklist.md +28 -0
- templates/meta/skills/python-meta-server/scripts/check_envelope.py +91 -0
- templates/meta/skills/react-vite-hub/SKILL.md +140 -0
- templates/meta/skills/react-vite-hub/assets/hub-ui-checklist.md +23 -0
- templates/meta/skills/react-vite-hub/scripts/check_vite_env.py +73 -0
- templates/meta/stack.yaml +119 -0
- templates/nestjs/rules/backend.md +20 -0
- templates/nestjs/scaffold/docs/engineering/nestjs-rules.md +33 -0
- templates/nestjs/scaffold/docs/playbooks/nestjs-service.md +39 -0
- templates/nestjs/scaffold/src/backend/nest-cli.json +5 -0
- templates/nestjs/scaffold/src/backend/package.json +28 -0
- templates/nestjs/scaffold/src/backend/src/app.module.ts +9 -0
- templates/nestjs/scaffold/src/backend/src/common/all-exceptions.filter.ts +59 -0
- templates/nestjs/scaffold/src/backend/src/health/health.controller.ts +14 -0
- templates/nestjs/scaffold/src/backend/src/health/health.module.ts +10 -0
- templates/nestjs/scaffold/src/backend/src/health/health.service.spec.ts +21 -0
- templates/nestjs/scaffold/src/backend/src/health/health.service.ts +9 -0
- templates/nestjs/scaffold/src/backend/src/main.ts +26 -0
- templates/nestjs/scaffold/src/backend/tsconfig.json +16 -0
- templates/nestjs/scaffold/src/backend/vitest.config.ts +9 -0
- templates/nestjs/scaffold-boundary.yaml +25 -0
- templates/nestjs/skills/nestjs/SKILL.md +67 -0
- templates/nestjs/skills/nestjs/references/anatomy.md +65 -0
- templates/nestjs/stack.yaml +68 -0
- templates/nextjs/rules/frontend.md +18 -0
- templates/nextjs/scaffold/docs/design/00-index.md +23 -0
- templates/nextjs/scaffold/docs/design/colors-tokens.md +141 -0
- templates/nextjs/scaffold/docs/design/components-patterns.md +159 -0
- templates/nextjs/scaffold/docs/design/motion-accessibility.md +137 -0
- templates/nextjs/scaffold/docs/design/typography-spacing.md +107 -0
- templates/nextjs/scaffold/docs/engineering/accessibility-web.md +56 -0
- templates/nextjs/scaffold/docs/engineering/copywriting-standard.md +102 -0
- templates/nextjs/scaffold/docs/engineering/formatting-rules.md +89 -0
- templates/nextjs/scaffold/docs/engineering/frontend-rendering-rules.md +80 -0
- templates/nextjs/scaffold/docs/engineering/frontend-rules.md +183 -0
- templates/nextjs/scaffold/docs/engineering/i18n-policy.md +99 -0
- templates/nextjs/scaffold/docs/pages-content-spec/00-index.md +78 -0
- templates/nextjs/scaffold/docs/playbooks/content-seo.md +55 -0
- templates/nextjs/scaffold/docs/playbooks/docs-governance.md +51 -0
- templates/nextjs/scaffold/docs/playbooks/frontend-ui.md +63 -0
- templates/nextjs/scaffold/src/frontend/app/layout.tsx +14 -0
- templates/nextjs/scaffold/src/frontend/app/page.tsx +3 -0
- templates/nextjs/scaffold/src/frontend/eslint.config.js +17 -0
- templates/nextjs/scaffold/src/frontend/lib/greeting.test.ts +9 -0
- templates/nextjs/scaffold/src/frontend/lib/greeting.ts +3 -0
- templates/nextjs/scaffold/src/frontend/package.json +28 -0
- templates/nextjs/scaffold/src/frontend/tsconfig.json +18 -0
- templates/nextjs/scaffold/src/frontend/vitest.config.ts +10 -0
- templates/nextjs/scaffold-boundary.yaml +30 -0
- templates/nextjs/skills/nextjs-react/SKILL.md +485 -0
- templates/nextjs/skills/nextjs-react/references/anatomy.md +116 -0
- templates/nextjs/skills/nextjs-react/scripts/new_component.py +72 -0
- templates/nextjs/stack.yaml +81 -0
- templates/node-express/rules/backend.md +20 -0
- templates/node-express/scaffold/docs/engineering/express-rules.md +30 -0
- templates/node-express/scaffold/docs/playbooks/express-service.md +35 -0
- templates/node-express/scaffold/src/backend/package.json +24 -0
- templates/node-express/scaffold/src/backend/src/index.ts +17 -0
- templates/node-express/scaffold/src/backend/src/middleware/error-handler.ts +12 -0
- templates/node-express/scaffold/src/backend/src/routes/health.test.ts +33 -0
- templates/node-express/scaffold/src/backend/src/routes/health.ts +7 -0
- templates/node-express/scaffold/src/backend/tsconfig.json +15 -0
- templates/node-express/scaffold/src/backend/types/express-bootstrap.d.ts +21 -0
- templates/node-express/scaffold-boundary.yaml +25 -0
- templates/node-express/skills/node-express/SKILL.md +70 -0
- templates/node-express/skills/node-express/references/anatomy.md +63 -0
- templates/node-express/stack.yaml +63 -0
- templates/python/scaffold/docs/engineering/python-rules.md +27 -0
- templates/python/scaffold/docs/playbooks/python-library.md +35 -0
- templates/python/stack.yaml +60 -0
- templates/rails/rules/backend.md +10 -0
- templates/rails/scaffold/docs/engineering/rails-rules.md +33 -0
- templates/rails/scaffold/docs/playbooks/rails-service.md +42 -0
- templates/rails/scaffold/src/backend/Gemfile +12 -0
- templates/rails/scaffold/src/backend/app/controllers/application_controller.rb +26 -0
- templates/rails/scaffold/src/backend/app/controllers/health_controller.rb +6 -0
- templates/rails/scaffold/src/backend/app/models/health.rb +6 -0
- templates/rails/scaffold/src/backend/config/application.rb +12 -0
- templates/rails/scaffold/src/backend/config/boot.rb +3 -0
- templates/rails/scaffold/src/backend/config/routes.rb +4 -0
- templates/rails/scaffold/src/backend/config.ru +5 -0
- templates/rails/scaffold/src/backend/spec/rails_helper.rb +18 -0
- templates/rails/scaffold/src/backend/spec/requests/health_spec.rb +24 -0
- templates/rails/scaffold-boundary.yaml +25 -0
- templates/rails/skills/rails/SKILL.md +62 -0
- templates/rails/skills/rails/references/anatomy.md +71 -0
- templates/rails/stack.yaml +72 -0
- templates/react-native/rules/mobile.md +26 -0
- templates/react-native/scaffold/docs/engineering/accessibility-mobile.md +95 -0
- templates/react-native/scaffold/docs/engineering/mobile-rules.md +56 -0
- templates/react-native/scaffold/docs/engineering/offline-first.md +61 -0
- templates/react-native/scaffold/docs/playbooks/mobile-app.md +49 -0
- templates/react-native/scaffold/src/mobile/App.tsx +9 -0
- templates/react-native/scaffold/src/mobile/eslint.config.js +17 -0
- templates/react-native/scaffold/src/mobile/package.json +23 -0
- templates/react-native/scaffold/src/mobile/src/greeting.test.ts +9 -0
- templates/react-native/scaffold/src/mobile/src/greeting.ts +3 -0
- templates/react-native/scaffold/src/mobile/tsconfig.json +17 -0
- templates/react-native/scaffold/src/mobile/vitest.config.ts +10 -0
- templates/react-native/scaffold-boundary.yaml +30 -0
- templates/react-native/skills/react-native-mobile/SKILL.md +119 -0
- templates/react-native/skills/react-native-mobile/assets/rn-mobile-checklist.md +28 -0
- templates/react-native/skills/react-native-mobile/references/anatomy.md +140 -0
- templates/react-native/skills/react-native-mobile/references/rn-2026-practices.md +54 -0
- templates/react-native/skills/react-native-mobile/scripts/new_screen.py +73 -0
- templates/react-native/skills/react-native-mobile/versions.json +16 -0
- templates/react-native/skills/react-native-patterns/SKILL.md +512 -0
- templates/react-native/skills/react-native-patterns/assets/rn-review-checklist.md +26 -0
- templates/react-native/skills/react-native-patterns/references/anatomy.md +62 -0
- templates/react-native/skills/react-native-patterns/references/list-performance.md +70 -0
- templates/react-native/skills/react-native-patterns/scripts/scan_rn_perf.py +77 -0
- templates/react-native/stack.yaml +70 -0
- templates/ruby-plain/scaffold/src/backend/Gemfile +8 -0
- templates/ruby-plain/scaffold/src/backend/main.rb +3 -0
- templates/ruby-plain/scaffold-boundary.yaml +23 -0
- templates/ruby-plain/stack.yaml +50 -0
- templates/rust-axum/rules/backend.md +20 -0
- templates/rust-axum/scaffold/docs/engineering/rust-axum-rules.md +35 -0
- templates/rust-axum/scaffold/docs/playbooks/rust-axum-service.md +43 -0
- templates/rust-axum/scaffold/src/backend/Cargo.toml +20 -0
- templates/rust-axum/scaffold/src/backend/src/app.rs +12 -0
- templates/rust-axum/scaffold/src/backend/src/error.rs +48 -0
- templates/rust-axum/scaffold/src/backend/src/main.rs +24 -0
- templates/rust-axum/scaffold/src/backend/src/routes/health.rs +37 -0
- templates/rust-axum/scaffold/src/backend/src/routes/mod.rs +2 -0
- templates/rust-axum/scaffold-boundary.yaml +25 -0
- templates/rust-axum/skills/rust/SKILL.md +73 -0
- templates/rust-axum/skills/rust/references/anatomy.md +63 -0
- templates/rust-axum/stack.yaml +65 -0
- templates/rust-plain/scaffold/src/backend/Cargo.toml +6 -0
- templates/rust-plain/scaffold/src/backend/src/main.rs +3 -0
- templates/rust-plain/scaffold-boundary.yaml +23 -0
- templates/rust-plain/stack.yaml +51 -0
- templates/spring-boot/rules/backend.md +20 -0
- templates/spring-boot/scaffold/docs/engineering/spring-boot-rules.md +35 -0
- templates/spring-boot/scaffold/docs/playbooks/spring-boot-service.md +45 -0
- templates/spring-boot/scaffold/src/backend/mvnw +302 -0
- templates/spring-boot/scaffold/src/backend/pom.xml +69 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/Application.java +16 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/common/GlobalExceptionHandler.java +31 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/health/HealthController.java +22 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/health/HealthService.java +12 -0
- templates/spring-boot/scaffold/src/backend/src/main/java/com/example/app/health/HealthStatus.java +4 -0
- templates/spring-boot/scaffold/src/backend/src/test/java/com/example/app/health/HealthServiceTest.java +15 -0
- templates/spring-boot/scaffold-boundary.yaml +26 -0
- templates/spring-boot/skills/spring-boot/SKILL.md +84 -0
- templates/spring-boot/skills/spring-boot/references/anatomy.md +63 -0
- templates/spring-boot/stack.yaml +65 -0
- templates/svelte-sveltekit/rules/frontend.md +20 -0
- templates/svelte-sveltekit/scaffold/docs/engineering/svelte-sveltekit-rules.md +37 -0
- templates/svelte-sveltekit/scaffold/docs/playbooks/svelte-sveltekit-app.md +36 -0
- templates/svelte-sveltekit/scaffold/src/frontend/package.json +22 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/app.html +12 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/hooks.server.ts +14 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/lib/components/Greeting.svelte +6 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/lib/stores/count.test.ts +26 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/lib/stores/count.ts +4 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/+layout.svelte +24 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/+page.svelte +9 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/+page.ts +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/src/routes/health/+server.ts +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/svelte.config.js +10 -0
- templates/svelte-sveltekit/scaffold/src/frontend/tsconfig.json +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/vite.config.ts +7 -0
- templates/svelte-sveltekit/scaffold/src/frontend/vitest.config.ts +11 -0
- templates/svelte-sveltekit/scaffold-boundary.yaml +29 -0
- templates/svelte-sveltekit/skills/svelte/SKILL.md +90 -0
- templates/svelte-sveltekit/skills/svelte/references/anatomy.md +62 -0
- templates/svelte-sveltekit/stack.yaml +70 -0
- templates/typescript-plain/scaffold/src/index.ts +3 -0
- templates/typescript-plain/scaffold/tsconfig.json +13 -0
- templates/typescript-plain/scaffold-boundary.yaml +22 -0
- templates/typescript-plain/stack.yaml +44 -0
- templates/vue-nuxt/rules/frontend.md +19 -0
- templates/vue-nuxt/scaffold/docs/engineering/nuxt-rules.md +30 -0
- templates/vue-nuxt/scaffold/docs/playbooks/nuxt-app.md +29 -0
- templates/vue-nuxt/scaffold/src/frontend/app.vue +3 -0
- templates/vue-nuxt/scaffold/src/frontend/nuxt.config.ts +11 -0
- templates/vue-nuxt/scaffold/src/frontend/package.json +20 -0
- templates/vue-nuxt/scaffold/src/frontend/pages/index.test.ts +19 -0
- templates/vue-nuxt/scaffold/src/frontend/pages/index.vue +11 -0
- templates/vue-nuxt/scaffold/src/frontend/vitest.config.ts +12 -0
- templates/vue-nuxt/scaffold-boundary.yaml +26 -0
- templates/vue-nuxt/skills/vue-nuxt/SKILL.md +57 -0
- templates/vue-nuxt/skills/vue-nuxt/references/anatomy.md +60 -0
- templates/vue-nuxt/stack.yaml +61 -0
- templates/wordpress/rules/backend.md +19 -0
- templates/wordpress/scaffold/docs/engineering/wordpress-rules.md +28 -0
- templates/wordpress/scaffold/docs/playbooks/wordpress-service.md +29 -0
- templates/wordpress/scaffold/src/backend/composer.json +17 -0
- templates/wordpress/scaffold/src/backend/phpcs.xml.dist +11 -0
- templates/wordpress/scaffold/src/backend/phpunit.xml +10 -0
- templates/wordpress/scaffold/src/backend/plugin/inc/health.php +8 -0
- templates/wordpress/scaffold/src/backend/plugin/plugin.php +28 -0
- templates/wordpress/scaffold/src/backend/tests/HealthStatusTest.php +15 -0
- templates/wordpress/scaffold/src/backend/theme/functions.php +18 -0
- templates/wordpress/scaffold/src/backend/theme/style.css +11 -0
- templates/wordpress/scaffold-boundary.yaml +23 -0
- templates/wordpress/skills/wordpress/SKILL.md +110 -0
- templates/wordpress/skills/wordpress/assets/wp-checklist.md +28 -0
- templates/wordpress/skills/wordpress/references/wp-development.md +75 -0
- templates/wordpress/skills/wordpress/references/wp-security.md +68 -0
- templates/wordpress/skills/wordpress/scripts/scan_wp_smells.py +91 -0
- templates/wordpress/skills/wordpress/versions.json +16 -0
- templates/wordpress/stack.yaml +60 -0
- thinking_os/__init__.py +1 -0
- thinking_os/_agent_markers.py +32 -0
- thinking_os/background.py +405 -0
- thinking_os/bootstrap_outcomes.py +200 -0
- thinking_os/budget.py +302 -0
- thinking_os/capture.py +495 -0
- thinking_os/cognition.py +516 -0
- thinking_os/cognition_schemas.py +517 -0
- thinking_os/compress.py +192 -0
- thinking_os/concepts.py +233 -0
- thinking_os/dashboard.py +159 -0
- thinking_os/database.py +2883 -0
- thinking_os/decay.py +393 -0
- thinking_os/digest.py +295 -0
- thinking_os/dispatcher.py +192 -0
- thinking_os/dispatcher_helpers.py +48 -0
- thinking_os/dispatchers/__init__.py +3 -0
- thinking_os/dispatchers/default.py +47 -0
- thinking_os/distill.py +192 -0
- thinking_os/doc_indexer.py +905 -0
- thinking_os/embeddings.py +943 -0
- thinking_os/formula_composer.py +556 -0
- thinking_os/gate_marker.py +75 -0
- thinking_os/graph.py +296 -0
- thinking_os/graph_indexer.py +360 -0
- thinking_os/health_check.py +517 -0
- thinking_os/impact.py +119 -0
- thinking_os/memory_gc.py +356 -0
- thinking_os/migrator_embeddings.py +318 -0
- thinking_os/precision.py +194 -0
- thinking_os/record_outcome.py +399 -0
- thinking_os/repair.py +105 -0
- thinking_os/retrieval_quality.py +239 -0
- thinking_os/roles_state.py +168 -0
- thinking_os/sanitizer.py +320 -0
- thinking_os/server.py +3160 -0
- thinking_os/session_enrich.py +272 -0
- thinking_os/session_observe_worker.py +111 -0
- thinking_os/session_startup.py +74 -0
- thinking_os/session_summary.py +245 -0
- thinking_os/task_analyzer.py +462 -0
- thinking_os/task_parser.py +342 -0
- thinking_os/task_sync.py +73 -0
- thinking_os/tools/__init__.py +6 -0
- thinking_os/tools/_shared.py +947 -0
- thinking_os/tools/cognition.py +1867 -0
- thinking_os/tools/docs.py +770 -0
- thinking_os/tools/learning.py +2078 -0
- thinking_os/tools/logs.py +79 -0
- thinking_os/tools/memory.py +840 -0
- thinking_os/tools/metrics.py +200 -0
- thinking_os/tools/retrieve.py +415 -0
- thinking_os/tools/routing.py +658 -0
- thinking_os/tools/tasks.py +449 -0
- thinking_os/tools/trajectory.py +181 -0
- thinking_os/tracing.py +235 -0
- web/__init__.py +5 -0
- web/_cache.py +118 -0
- web/_deps.py +56 -0
- web/_envelope.py +85 -0
- web/_project_context.py +140 -0
- web/chat_providers.py +108 -0
- web/init_jobs.py +216 -0
- web/routes/__init__.py +25 -0
- web/routes/_bounded_read.py +76 -0
- web/routes/board.py +1089 -0
- web/routes/cognition.py +1838 -0
- web/routes/config.py +635 -0
- web/routes/graph.py +513 -0
- web/routes/health.py +180 -0
- web/routes/hooks.py +288 -0
- web/routes/hub.py +1219 -0
- web/routes/logs.py +374 -0
- web/routes/metrics.py +43 -0
- web/routes/observability.py +400 -0
- web/routes/patterns.py +227 -0
- web/routes/presence.py +609 -0
- web/routes/roles.py +446 -0
- web/routes/scheduled.py +261 -0
- web/routes/search.py +238 -0
- web/routes/sessions.py +220 -0
- web/routes/settings.py +363 -0
- web/routes/stream.py +547 -0
- web/security.py +157 -0
- web/server.py +283 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: Block direct edits to protected files.
|
|
3
|
+
# Protected:
|
|
4
|
+
# - changes.log (use make log-write)
|
|
5
|
+
# - Governance files: agent rules/, hooks/, CLAUDE.md, AGENTS.md,
|
|
6
|
+
# infrastructure/scripts/ — never edit as side-effect of another task.
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
10
|
+
|
|
11
|
+
# Fail-closed: a protected-file gate that cannot read the path must DENY,
|
|
12
|
+
# not silently allow when jq is absent (observability-eye I8).
|
|
13
|
+
cos_require_parser block-protected-files
|
|
14
|
+
|
|
15
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
16
|
+
FILE_PATH=$(printf '%s' "$INPUT" | cos_json_field tool_input.file_path)
|
|
17
|
+
|
|
18
|
+
# Block direct edits to changes.log
|
|
19
|
+
if [[ "$FILE_PATH" == *"changes.log"* ]]; then
|
|
20
|
+
echo "BLOCKED: Do not edit changes.log directly. Use 'make log-write TYPE=<type> MSG=\"title\" WHAT=\"impact\" FILES=\"files\"'." >&2
|
|
21
|
+
exit 2
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Scrumban task status changes go through `cos task-move` / `cos task-done`,
|
|
25
|
+
# never a hand-edit of a task file — validate-task-frontmatter.sh guards that.
|
|
26
|
+
|
|
27
|
+
# Block edits to governance/workflow files unless explicitly tasked.
|
|
28
|
+
# These define HOW we work — changing them as a side-effect of another task
|
|
29
|
+
# can silently break workflow for all future sessions.
|
|
30
|
+
#
|
|
31
|
+
# Exception: paths inside templates/.../scaffold/ are SCAFFOLD TEMPLATES, not
|
|
32
|
+
# runtime state. They need to be writable so coding-os itself can ship updates
|
|
33
|
+
# to the scaffold (e.g. adding rag-config.yaml under .coding-os/ scaffold).
|
|
34
|
+
# BUT: scaffold/docs/governance/ is the canonical home of governance docs
|
|
35
|
+
# that propagate to every future consumer project require the
|
|
36
|
+
# same template-update / governance / docs-update keyword guard the
|
|
37
|
+
# meta-repo's own governance dir uses. Other scaffold paths still pass.
|
|
38
|
+
if [[ "$FILE_PATH" == *"/scaffold/docs/governance/"* ]]; then
|
|
39
|
+
AGENT_DIR="${COS_AGENT_DIR:-${COS_STATE_DIR:-.coding-os}/${COS_AGENT:-unknown}}"
|
|
40
|
+
# Panel-aware lookup — task marker lives in $COS_PANEL_DIR
|
|
41
|
+
# since the per-panel split. Falls through cleanly when COS_PANEL_DIR
|
|
42
|
+
# is unset (older hook caller).
|
|
43
|
+
TASK_FILE="${COS_PANEL_DIR:-$AGENT_DIR}/.task-current"
|
|
44
|
+
TASK_NAME=""
|
|
45
|
+
if [ -f "$TASK_FILE" ]; then
|
|
46
|
+
TASK_VALUE=$(cat "$TASK_FILE" 2>/dev/null)
|
|
47
|
+
# Strip ONLY the leading session-id token; keep the rest of the value.
|
|
48
|
+
# `##* ` would drop everything but the LAST word, so a multi-word marker
|
|
49
|
+
# (`<sid> docs-update TASK-NNN align-docs`) lost the governance keyword.
|
|
50
|
+
TASK_NAME="${TASK_VALUE#* }"
|
|
51
|
+
fi
|
|
52
|
+
case "$TASK_NAME" in
|
|
53
|
+
*template-update*|*docs-update*|*docs-sync*|*governance*|*claude-md-update*|*agents-md-update*)
|
|
54
|
+
exit 0
|
|
55
|
+
;;
|
|
56
|
+
*)
|
|
57
|
+
echo "BLOCKED: Edits to src/templates/_base/scaffold/docs/governance/ propagate to every future consumer project. Open a task whose title includes one of: template-update, docs-update, governance. Active task: '${TASK_NAME:-none}'." >&2
|
|
58
|
+
exit 2
|
|
59
|
+
;;
|
|
60
|
+
esac
|
|
61
|
+
fi
|
|
62
|
+
if [[ "$FILE_PATH" == *"/scaffold/"* ]]; then
|
|
63
|
+
exit 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Data-driven adapter state protection: every adapter declares a state
|
|
67
|
+
# dir (e.g. `.claude/`, `.codex/`) — we block edits under any
|
|
68
|
+
# of them. Discovery order:
|
|
69
|
+
# 1. src/adapters/<id>/adapter.yaml (source of truth in the meta-repo)
|
|
70
|
+
# 2. legacy hardcoded safety-net for meta-project setups that pre-date
|
|
71
|
+
# the registry (cannot regress; this list is additive).
|
|
72
|
+
ADAPTER_ROOT="$(cd "$(dirname "$0")/../.." 2>/dev/null && pwd)/adapters"
|
|
73
|
+
ADAPTER_STATE_GLOB=""
|
|
74
|
+
if [ -d "$ADAPTER_ROOT" ]; then
|
|
75
|
+
for adir in "$ADAPTER_ROOT"/*/; do
|
|
76
|
+
[ -d "$adir" ] || continue
|
|
77
|
+
aid=$(basename "$adir")
|
|
78
|
+
ADAPTER_STATE_GLOB="${ADAPTER_STATE_GLOB}|.${aid}/rules/|.${aid}/hooks/|.${aid}/skills/"
|
|
79
|
+
done
|
|
80
|
+
fi
|
|
81
|
+
ADAPTER_STATE_GLOB="${ADAPTER_STATE_GLOB}|.claude/rules/|.claude/hooks/|.codex/hooks/"
|
|
82
|
+
|
|
83
|
+
matched_adapter_path=0
|
|
84
|
+
IFS='|' read -r -a _glob_parts <<< "$ADAPTER_STATE_GLOB"
|
|
85
|
+
for _g in "${_glob_parts[@]}"; do
|
|
86
|
+
[ -z "$_g" ] && continue
|
|
87
|
+
if [[ "$FILE_PATH" == *"$_g"* ]]; then
|
|
88
|
+
matched_adapter_path=1
|
|
89
|
+
break
|
|
90
|
+
fi
|
|
91
|
+
done
|
|
92
|
+
|
|
93
|
+
# Protect the src/core/ skill+rule SOURCE too: it propagates to every consumer
|
|
94
|
+
# via live symlinks, so it needs the same guard as its rendered .claude/ copies.
|
|
95
|
+
if [[ "$matched_adapter_path" -eq 1 ]] || \
|
|
96
|
+
[[ "$FILE_PATH" == *".coding-os/"* ]] || \
|
|
97
|
+
[[ "$FILE_PATH" == *"/CLAUDE.md" ]] || \
|
|
98
|
+
[[ "$FILE_PATH" == *"/AGENTS.md" ]] || \
|
|
99
|
+
[[ "$FILE_PATH" == *"src/core/skills/"* ]] || \
|
|
100
|
+
[[ "$FILE_PATH" == *"src/core/rules/"* ]] || \
|
|
101
|
+
[[ "$FILE_PATH" == *"infrastructure/scripts/"* ]]; then
|
|
102
|
+
# Escape hatch: if the active task explicitly names governance work,
|
|
103
|
+
# allow the edit. This prevents genuine docs/governance tasks from
|
|
104
|
+
# being blocked by the safety net. The active task marker is session-
|
|
105
|
+
# scoped and set via `cos task-start` or write-state.sh.
|
|
106
|
+
# Task marker lives in the panel-private state dir (COS_PANEL_DIR per
|
|
107
|
+
# ); fall back to agent dir only when cos-env.sh hasn't been
|
|
108
|
+
# sourced. Falls through cleanly during the transition window.
|
|
109
|
+
AGENT_DIR="${COS_AGENT_DIR:-${COS_STATE_DIR:-.coding-os}/${COS_AGENT:-unknown}}"
|
|
110
|
+
TASK_FILE="${COS_PANEL_DIR:-$AGENT_DIR}/.task-current"
|
|
111
|
+
if [ -f "$TASK_FILE" ]; then
|
|
112
|
+
TASK_VALUE=$(cat "$TASK_FILE" 2>/dev/null)
|
|
113
|
+
# The task marker is "session-id value" — extract the value
|
|
114
|
+
# Strip ONLY the leading session-id token; keep the rest of the value.
|
|
115
|
+
# `##* ` would drop everything but the LAST word, so a multi-word marker
|
|
116
|
+
# (`<sid> docs-update TASK-NNN align-docs`) lost the governance keyword.
|
|
117
|
+
TASK_NAME="${TASK_VALUE#* }"
|
|
118
|
+
# Allow when the task name clearly signals governance/docs work.
|
|
119
|
+
case "$TASK_NAME" in
|
|
120
|
+
*docs-update*|*docs-sync*|*governance*|*claude-md-update*|*agents-md-update*)
|
|
121
|
+
exit 0
|
|
122
|
+
;;
|
|
123
|
+
esac
|
|
124
|
+
fi
|
|
125
|
+
echo "BLOCKED: Governance/workflow file detected. Do not edit agent config dirs, src/core/skills/ or src/core/rules/ sources, CLAUDE.md, AGENTS.md, or infrastructure/scripts/ as a side-effect of another task. Create a dedicated task whose title includes governance or docs-update, e.g. write-state.sh ${COS_PANEL_DIR:-$AGENT_DIR}/.task-current 'docs-update-...'" >&2
|
|
126
|
+
exit 2
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
exit 0
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse hook: Block commits/writes containing hardcoded secrets or sensitive files.
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
6
|
+
if ! command -v cos_log_hook >/dev/null 2>&1; then cos_log_hook() { :; }; fi
|
|
7
|
+
|
|
8
|
+
# Fail-closed: a secret-scanning gate that cannot read its input must DENY,
|
|
9
|
+
# not silently allow (observability-eye I8). cos_json_field falls back to
|
|
10
|
+
# python3 when only jq is missing, so the gate keeps working.
|
|
11
|
+
cos_require_parser block-secrets
|
|
12
|
+
|
|
13
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
14
|
+
|
|
15
|
+
# Fast-path: this gate fires on EVERY Bash command. The Bash leg only ever
|
|
16
|
+
# blocks `git add` of a secret file, a hook-skipping `git commit`
|
|
17
|
+
# (--no-verify/-n), or a `core.hooksPath` override; if the raw payload mentions
|
|
18
|
+
# none AND is not a Write/Edit (whose content we must scan), there is nothing to
|
|
19
|
+
# deny — bail before any jq spawn. The hooksPath token is matched in its two
|
|
20
|
+
# realistic casings (the deep grep below is case-insensitive). Write/Edit
|
|
21
|
+
# payloads always carry "new_string"/"content", so they never match here.
|
|
22
|
+
case "$INPUT" in
|
|
23
|
+
*"git add"*|*git*commit*|*hooksPath*|*hookspath*|*new_string*|*'"content"'*) ;;
|
|
24
|
+
*) exit 0 ;;
|
|
25
|
+
esac
|
|
26
|
+
|
|
27
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
28
|
+
|
|
29
|
+
# For Bash tool: block git add of sensitive files
|
|
30
|
+
if [[ "$TOOL" == "Bash" ]]; then
|
|
31
|
+
cos_log_hook block-secrets fire "tool=Bash"
|
|
32
|
+
COMMAND=$(printf '%s' "$INPUT" | cos_json_field tool_input.command)
|
|
33
|
+
|
|
34
|
+
# Block git add of .env files (but allow .env.example, .env.template)
|
|
35
|
+
if echo "$COMMAND" | grep -qE 'git add.*\.env($|\s)' || echo "$COMMAND" | grep -qE 'git add\s+\.env$'; then
|
|
36
|
+
cos_log_hook block-secrets block "tool=Bash rule=env-file"
|
|
37
|
+
echo "BLOCKED: .env files must not be committed to git. Use .env.example for structure." >&2
|
|
38
|
+
exit 2
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Block git add of credential/key files
|
|
42
|
+
if echo "$COMMAND" | grep -qE 'git add.*(credentials\.json|service-account\.json|\.pem\b|id_rsa|\.key\b)'; then
|
|
43
|
+
cos_log_hook block-secrets block "tool=Bash rule=credential-file"
|
|
44
|
+
echo "BLOCKED: Credential/key files must not be committed. Store secrets in environment variables." >&2
|
|
45
|
+
exit 2
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Block any git-commit that skips the verify hooks (--no-verify / -n /
|
|
49
|
+
# core.hooksPath / GIT_CONFIG_* injection). Delegated to a shlex-tokenizing
|
|
50
|
+
# helper: the old bash regex ran over a quote-STRIPPED string, so a spliced
|
|
51
|
+
# `--no-ver"i"fy`, a quoted `"-n"`, or a `GIT_CONFIG_*` env prefix vanished
|
|
52
|
+
# from the scan yet bash still executed it (TASK-567). `_cos_helpers_dir`
|
|
53
|
+
# (cos-env.sh) resolves the physical `_helpers/` through the .claude/ symlink.
|
|
54
|
+
BYPASS_HELPER="$(_cos_helpers_dir)/check_git_bypass.py"
|
|
55
|
+
BYPASS_VERDICT=$(printf '%s' "$INPUT" | python3 "$BYPASS_HELPER" 2>/dev/null || echo error)
|
|
56
|
+
# Fail-closed but SCOPED: a helper crash blocks only when the raw command
|
|
57
|
+
# actually carries a commit/hooksPath/GIT_CONFIG token we could not verify.
|
|
58
|
+
if [ "$BYPASS_VERDICT" = "error" ]; then
|
|
59
|
+
case "$COMMAND" in
|
|
60
|
+
*commit*|*hooksPath*|*hookspath*|*GIT_CONFIG*) BYPASS_VERDICT='{"verdict":"block"}' ;;
|
|
61
|
+
*) BYPASS_VERDICT='{"verdict":"allow"}' ;;
|
|
62
|
+
esac
|
|
63
|
+
fi
|
|
64
|
+
if printf '%s' "$BYPASS_VERDICT" | grep -qE '"verdict": *"block"'; then
|
|
65
|
+
cos_log_hook block-secrets block "tool=Bash rule=no-verify"
|
|
66
|
+
_bs_msg=$(printf '%s' "$BYPASS_VERDICT" | cos_json_field message 2>/dev/null || echo "")
|
|
67
|
+
echo "${_bs_msg:-BLOCKED: skipping git verify hooks (--no-verify / -n / core.hooksPath). Fix the underlying issue, do not bypass.}" >&2
|
|
68
|
+
exit 2
|
|
69
|
+
fi
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# For Write/Edit tool: block writing secrets patterns
|
|
73
|
+
if [[ "$TOOL" == "Write" || "$TOOL" == "Edit" ]]; then
|
|
74
|
+
FILE_PATH=$(printf '%s' "$INPUT" | cos_json_field tool_input.file_path)
|
|
75
|
+
CONTENT=$(printf '%s' "$INPUT" | cos_json_field tool_input.new_string tool_input.content)
|
|
76
|
+
FILE_BASENAME="$(basename "$FILE_PATH" 2>/dev/null || echo "")"
|
|
77
|
+
|
|
78
|
+
# Skip docs + genuine test/mock files. Match path SEGMENTS / basenames, not
|
|
79
|
+
# bare substrings — `*test*` used to skip ANY path containing "test"
|
|
80
|
+
# (latest/, contest/), silently disabling secret scanning there.
|
|
81
|
+
case "$FILE_PATH" in
|
|
82
|
+
*.env.example*|*.md|*.markdown) exit 0 ;;
|
|
83
|
+
*/tests/*|*/test/*|*/__tests__/*|*/__mocks__/*|*/mocks/*|*/fixtures/*) exit 0 ;;
|
|
84
|
+
esac
|
|
85
|
+
case "$FILE_BASENAME" in
|
|
86
|
+
test_*|*_test.*|*.test.*|*.spec.*|mock_*|*_mock.*|conftest.py) exit 0 ;;
|
|
87
|
+
esac
|
|
88
|
+
|
|
89
|
+
# Block live Stripe keys (sk_live_, pk_live_ with real-length values)
|
|
90
|
+
if echo "$CONTENT" | grep -qE 'sk_live_[a-zA-Z0-9]{20,}'; then
|
|
91
|
+
echo "BLOCKED: Live Stripe secret key detected. Use environment variables (os.environ['STRIPE_SECRET_KEY']) instead." >&2
|
|
92
|
+
exit 2
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Block test Stripe keys hardcoded in non-test files
|
|
96
|
+
if [[ "$FILE_PATH" != *test* ]] && [[ "$FILE_PATH" != *fixture* ]] && [[ "$FILE_PATH" != *.env* ]]; then
|
|
97
|
+
if echo "$CONTENT" | grep -qE 'sk_test_[a-zA-Z0-9]{20,}'; then
|
|
98
|
+
echo "BLOCKED: Stripe test key should be in .env, not hardcoded. Use environment variables." >&2
|
|
99
|
+
exit 2
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# Block private keys
|
|
104
|
+
if echo "$CONTENT" | grep -qE 'BEGIN (RSA |EC |OPENSSH |DSA )?PRIVATE KEY'; then
|
|
105
|
+
echo "BLOCKED: Private key detected in file content. Store keys in environment variables or secret manager." >&2
|
|
106
|
+
exit 2
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Block AWS credentials
|
|
110
|
+
if echo "$CONTENT" | grep -qE 'AKIA[0-9A-Z]{16}'; then
|
|
111
|
+
echo "BLOCKED: AWS access key ID detected. Use environment variables or IAM roles." >&2
|
|
112
|
+
exit 2
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Block generic high-entropy secrets (API keys, tokens) in Python/TS config files
|
|
116
|
+
if [[ "$FILE_PATH" == *settings* ]] || [[ "$FILE_PATH" == *config* ]] || [[ "$FILE_PATH" == *.env* ]]; then
|
|
117
|
+
if echo "$CONTENT" | grep -qE "(SECRET_KEY|API_KEY|AUTH_TOKEN|PRIVATE_KEY)\s*=\s*['\"][a-zA-Z0-9+/=]{32,}['\"]"; then
|
|
118
|
+
echo "BLOCKED: Hardcoded secret detected in config. Use os.environ.get() or environment variables." >&2
|
|
119
|
+
exit 2
|
|
120
|
+
fi
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# Block Django SECRET_KEY hardcoded.
|
|
124
|
+
# Tighten allowlist: match the file BASENAME, not the whole path, so a path
|
|
125
|
+
# containing "development" elsewhere (e.g. /var/development-team/app/settings.py)
|
|
126
|
+
# doesn't open a hole.
|
|
127
|
+
if echo "$CONTENT" | grep -qE "SECRET_KEY\s*=\s*['\"]django-insecure-"; then
|
|
128
|
+
if [[ "$FILE_BASENAME" != *development* ]] && [[ "$FILE_BASENAME" != *local* ]]; then
|
|
129
|
+
echo "BLOCKED: Insecure Django SECRET_KEY detected outside development settings. Use environment variables." >&2
|
|
130
|
+
exit 2
|
|
131
|
+
fi
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
# Block Postmark server token hardcoded
|
|
135
|
+
if echo "$CONTENT" | grep -qE 'POSTMARK_SERVER_TOKEN\s*=\s*["\047][a-f0-9-]{36}["\047]'; then
|
|
136
|
+
echo "BLOCKED: Postmark server token detected. Use environment variables." >&2
|
|
137
|
+
exit 2
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Block GitHub Personal Access Tokens (classic + fine-grained) and OAuth tokens.
|
|
141
|
+
# Format: ghp_/gho_/ghu_/ghs_/ghr_ + 36+ alnum.
|
|
142
|
+
if echo "$CONTENT" | grep -qE 'gh[pousr]_[A-Za-z0-9]{36,}'; then
|
|
143
|
+
echo "BLOCKED: GitHub token detected (ghp_/gho_/ghu_/ghs_/ghr_). Use \$GITHUB_TOKEN env var or gh auth login." >&2
|
|
144
|
+
exit 2
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# Block OpenAI / Anthropic API keys. The discriminator is the SPECIFIC prefix
|
|
148
|
+
# (sk-ant-api##- / sk-proj- / classic sk-+40 contiguous alnum) — kebab-case
|
|
149
|
+
# slugs like `sk-product-identifier-x` lack it and no longer false-fire. The
|
|
150
|
+
# ant/proj bodies still allow base64url `-`/`_` so real keys are caught.
|
|
151
|
+
if echo "$CONTENT" | grep -qE 'sk-ant-(api|admin)[0-9]{2}-[A-Za-z0-9_-]{80,}|sk-proj-[A-Za-z0-9_-]{40,}|sk-[A-Za-z0-9]{40,}'; then
|
|
152
|
+
echo "BLOCKED: OpenAI/Anthropic API key detected. Use environment variables (OPENAI_API_KEY, ANTHROPIC_API_KEY)." >&2
|
|
153
|
+
exit 2
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# Block Slack tokens (xoxb-/xoxa-/xoxp-/xoxr-/xoxs-).
|
|
157
|
+
if echo "$CONTENT" | grep -qE 'xox[abprs]-[A-Za-z0-9-]{10,}'; then
|
|
158
|
+
echo "BLOCKED: Slack token detected. Use environment variables." >&2
|
|
159
|
+
exit 2
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Block Google API keys (AIza...).
|
|
163
|
+
if echo "$CONTENT" | grep -qE 'AIza[A-Za-z0-9_\-]{35}'; then
|
|
164
|
+
echo "BLOCKED: Google API key detected. Use environment variables." >&2
|
|
165
|
+
exit 2
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
# Block JWT tokens hardcoded in source (header.payload.signature, base64url).
|
|
169
|
+
# Skip docs/examples — already filtered above. Require 3 segments with ≥10 chars each.
|
|
170
|
+
if echo "$CONTENT" | grep -qE 'eyJ[A-Za-z0-9_\-]{10,}\.eyJ[A-Za-z0-9_\-]{10,}\.[A-Za-z0-9_\-]{10,}'; then
|
|
171
|
+
echo "BLOCKED: JWT token detected hardcoded in source. Issue tokens at runtime; do not commit." >&2
|
|
172
|
+
exit 2
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# Block basic-auth credentials embedded in URLs (http(s)://user:password@host).
|
|
176
|
+
# Only block when the password segment has real entropy (≥6 chars, not just "user:pass" placeholder).
|
|
177
|
+
if echo "$CONTENT" | grep -qE 'https?://[A-Za-z0-9._-]+:[^@[:space:]/"\047]{6,}@[A-Za-z0-9.-]+'; then
|
|
178
|
+
if ! echo "$CONTENT" | grep -qE 'https?://(user|username|admin|root|test|example|foo):(password|pass|secret|test|example|foo|changeme)@'; then
|
|
179
|
+
echo "BLOCKED: Basic-auth credentials embedded in URL. Use env vars or a secret manager, never inline in URLs." >&2
|
|
180
|
+
exit 2
|
|
181
|
+
fi
|
|
182
|
+
fi
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
exit 0
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# block-shared-tree-edit.sh — pr-mode edit isolation (companion to branch-guard).
|
|
3
|
+
#
|
|
4
|
+
# In COS_GIT_WORKFLOW=pr, a Write/Edit on a file inside the SHARED integration
|
|
5
|
+
# checkout (the main repo, not a worktree) is BLOCKED so every code change is
|
|
6
|
+
# isolated in a worktree — even work the user said not to make a board task for
|
|
7
|
+
# (`cos pr open --adhoc`). Inert in trunk mode (the default), so coding-os and
|
|
8
|
+
# every trunk consumer pay one env check and exit. Files inside a worktree, and
|
|
9
|
+
# files outside the repo entirely (scratch, dotfiles), pass.
|
|
10
|
+
# SPEC: docs/playbooks/pr-workflow.md § 5/§6.
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
14
|
+
if ! command -v cos_log_hook >/dev/null 2>&1; then cos_log_hook() { :; }; fi
|
|
15
|
+
|
|
16
|
+
# Inert unless pr-mode — the common case, kept to a single comparison.
|
|
17
|
+
[[ "${COS_GIT_WORKFLOW:-trunk}" == "pr" ]] || exit 0
|
|
18
|
+
|
|
19
|
+
cos_require_parser block-shared-tree-edit
|
|
20
|
+
|
|
21
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
22
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
23
|
+
case "$TOOL" in
|
|
24
|
+
Write | Edit | MultiEdit) ;;
|
|
25
|
+
*) exit 0 ;;
|
|
26
|
+
esac
|
|
27
|
+
|
|
28
|
+
FILE=$(printf '%s' "$INPUT" | cos_json_field tool_input.file_path)
|
|
29
|
+
[[ -z "$FILE" ]] && exit 0
|
|
30
|
+
|
|
31
|
+
# Block only files inside the shared integration checkout = the main repo root
|
|
32
|
+
# (parent of COS_STATE_DIR). Edits elsewhere (scratch, ~/.config) pass through.
|
|
33
|
+
REPO_ROOT="$(cd -P "$(dirname "${COS_STATE_DIR}")" 2>/dev/null && pwd -P)" || REPO_ROOT=""
|
|
34
|
+
[[ -z "$REPO_ROOT" || "$REPO_ROOT" == "." ]] && exit 0
|
|
35
|
+
|
|
36
|
+
FILE_ABS="$FILE"
|
|
37
|
+
case "$FILE" in
|
|
38
|
+
/*) ;;
|
|
39
|
+
*) FILE_ABS="$(pwd)/$FILE" ;;
|
|
40
|
+
esac
|
|
41
|
+
# Resolve symlinks AND `..` in the parent path so the worktree / REPO_ROOT
|
|
42
|
+
# classification below tests the REAL path (Rule 5: /tmp ↔ /private/tmp). The
|
|
43
|
+
# file may not exist yet (new file), so resolve its dirname, not the file itself.
|
|
44
|
+
FILE_DIR="$(cd -P "$(dirname "$FILE_ABS")" 2>/dev/null && pwd -P)" || FILE_DIR=""
|
|
45
|
+
if [[ -n "$FILE_DIR" ]]; then
|
|
46
|
+
FILE_ABS="$FILE_DIR/$(basename "$FILE_ABS")"
|
|
47
|
+
elif command -v python3 >/dev/null 2>&1; then
|
|
48
|
+
# Parent dir doesn't exist yet (new nested file): collapse `..` lexically via
|
|
49
|
+
# os.path.realpath so a `..`-spoof can't keep a literal worktrees/ segment and
|
|
50
|
+
# slip through the worktree-allow below — matches the python sibling
|
|
51
|
+
# _is_worktree_path (review finding 4).
|
|
52
|
+
FILE_ABS="$(python3 -c 'import os,sys; print(os.path.realpath(sys.argv[1]))' "$FILE_ABS" 2>/dev/null || printf '%s' "$FILE_ABS")"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# A file under a worktree root IS the isolation target — allow. Classify the
|
|
56
|
+
# RESOLVED path so a `..`-traversal spoof that escapes the worktree can't pass.
|
|
57
|
+
case "$FILE_ABS" in
|
|
58
|
+
*"/.coding-os/worktrees/"*) exit 0 ;;
|
|
59
|
+
esac
|
|
60
|
+
if [[ -n "${COS_WORKTREE_ROOT:-}" && "$FILE_ABS" == "${COS_WORKTREE_ROOT}"/* ]]; then
|
|
61
|
+
exit 0
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
if [[ "$FILE_ABS" == "${REPO_ROOT}/"* ]]; then
|
|
65
|
+
cos_log_hook block-shared-tree-edit block "rule=pr-shared-tree-edit"
|
|
66
|
+
bash "$(dirname "$0")/../scripts/log-write.sh" \
|
|
67
|
+
--type "hook-block" --msg "block-shared-tree-edit" --what "$(basename "$FILE")" 2>/dev/null || true
|
|
68
|
+
echo "BLOCKED (pr-mode): editing a file in the shared integration checkout." >&2
|
|
69
|
+
echo " Every change must be isolated in a worktree, never the shared tree." >&2
|
|
70
|
+
echo " To fix: 'cos pr open' (or 'cos pr open --adhoc' for no-task work)," >&2
|
|
71
|
+
echo " then edit inside the worktree." >&2
|
|
72
|
+
echo " See docs/playbooks/pr-workflow.md § 5/§6." >&2
|
|
73
|
+
exit 2
|
|
74
|
+
fi
|
|
75
|
+
exit 0
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PreToolUse Bash hook: block `uv run ... <<` heredoc patterns.
|
|
3
|
+
#
|
|
4
|
+
# Source of truth: CLAUDE.md Critical Rule #9 — "Always use Python for
|
|
5
|
+
# multi-step verification scripts. Bash heredoc inside `$(...)` with
|
|
6
|
+
# `uv run` hangs. Write to a Python file and invoke via
|
|
7
|
+
# subprocess.run(..., timeout=N). See src/scripts/verify_phase_c_e2e.py."
|
|
8
|
+
#
|
|
9
|
+
# This hook matches three forms observed to hang or truncate silently:
|
|
10
|
+
# 1. `uv run python - <<'EOF' ... EOF` (stdin-piped Python)
|
|
11
|
+
# 2. `uv run python -c "$(cat <<'EOF' ...` (heredoc inside command-sub)
|
|
12
|
+
# 3. `output=$(uv run python - <<EOF ...)` (capture + stdin-piped)
|
|
13
|
+
#
|
|
14
|
+
# Escape hatch: touch $COS_AGENT_DIR/.uv-heredoc-override for one-shot bypass.
|
|
15
|
+
# Use sparingly — the Python-file pattern is almost always cleaner.
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
19
|
+
if ! command -v cos_log_hook >/dev/null 2>&1; then cos_log_hook() { :; }; fi
|
|
20
|
+
|
|
21
|
+
# Fail-closed: a heredoc-deadlock gate that cannot read the command must DENY,
|
|
22
|
+
# not silently allow when jq is absent (observability-eye I8). cos_json_field
|
|
23
|
+
# falls back to python3, so the gate keeps working when only jq is missing.
|
|
24
|
+
cos_require_parser block-uv-heredoc
|
|
25
|
+
|
|
26
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
27
|
+
|
|
28
|
+
# Fast-path: the only thing this gate blocks is `uv run … <<heredoc`. If the
|
|
29
|
+
# raw payload lacks either "uv" or a "<<" heredoc operator there is nothing to
|
|
30
|
+
# deny — bail before any jq spawn (this hook fires on EVERY Bash command).
|
|
31
|
+
case "$INPUT" in
|
|
32
|
+
*uv*) ;;
|
|
33
|
+
*) exit 0 ;;
|
|
34
|
+
esac
|
|
35
|
+
case "$INPUT" in
|
|
36
|
+
*'<<'*) ;;
|
|
37
|
+
*) exit 0 ;;
|
|
38
|
+
esac
|
|
39
|
+
|
|
40
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
41
|
+
if [[ "$TOOL" != "Bash" ]]; then
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
CMD=$(printf '%s' "$INPUT" | cos_json_field tool_input.command)
|
|
46
|
+
[[ -z "$CMD" ]] && exit 0
|
|
47
|
+
|
|
48
|
+
COS_STATE_DIR="${COS_STATE_DIR:-.coding-os}"
|
|
49
|
+
cos_log_hook block-uv-heredoc fire "tool=Bash"
|
|
50
|
+
|
|
51
|
+
# One-shot override (consumed on use). Unified registry checked first;
|
|
52
|
+
# legacy $COS_AGENT_DIR/.uv-heredoc-override still honoured.
|
|
53
|
+
if cos_one_shot_override uv-heredoc 2>/dev/null; then
|
|
54
|
+
cos_log_hook block-uv-heredoc bypass "reason=override"
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Detect `uv run` followed (within reasonable distance) by heredoc operator.
|
|
59
|
+
# We accept `<<`, `<<-`, `<<'EOF'`, `<<"EOF"`, `<<EOF` variants.
|
|
60
|
+
if echo "$CMD" | grep -qE 'uv[[:space:]]+run[^|&;]*<<'; then
|
|
61
|
+
cos_log_hook block-uv-heredoc block "rule=uv-run-heredoc"
|
|
62
|
+
echo "BLOCKED: \`uv run\` with heredoc is known to hang silently." >&2
|
|
63
|
+
echo " CLAUDE.md Critical Rule #9 — always use a real Python file:" >&2
|
|
64
|
+
echo "" >&2
|
|
65
|
+
echo " # write the script" >&2
|
|
66
|
+
echo " cat > src/scripts/my_check.py <<'PY'" >&2
|
|
67
|
+
echo " ..." >&2
|
|
68
|
+
echo " PY" >&2
|
|
69
|
+
echo "" >&2
|
|
70
|
+
echo " # then invoke via subprocess-friendly single-quoted path" >&2
|
|
71
|
+
echo " uv run --extra rag python src/scripts/my_check.py" >&2
|
|
72
|
+
echo "" >&2
|
|
73
|
+
echo " Reference: src/scripts/verify_phase_c_e2e.py" >&2
|
|
74
|
+
echo " One-shot override: touch $COS_AGENT_DIR/.uv-heredoc-override" >&2
|
|
75
|
+
exit 2
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
exit 0
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# branch-guard.sh — enforce trunk-based git integrity.
|
|
3
|
+
#
|
|
4
|
+
# PreToolUse:Bash hook. In trunk mode (default) it BLOCKs commands that
|
|
5
|
+
# either (a) create a branch / worktree or (b) rewrite shared HEAD —
|
|
6
|
+
# both classes can clobber a peer session's commits or scatter work
|
|
7
|
+
# across phantom branches. The coding-os workflow commits directly to
|
|
8
|
+
# main (see src/core/rules/git-workflow.md). COS_GIT_WORKFLOW=pr switches to a
|
|
9
|
+
# positive pr-mode policy (consumer-only): agents/* branches + worktrees pass,
|
|
10
|
+
# but the shared checkout and protected branches stay guarded — NOT a bypass.
|
|
11
|
+
#
|
|
12
|
+
# The actual parsing lives in _helpers/branch_guard_check.py — it
|
|
13
|
+
# handles whitespace normalization, `git -C` / `git -c` global options,
|
|
14
|
+
# nested `sh -c "..."` / `bash -c "..."`, command-segment splitting,
|
|
15
|
+
# and `shlex` quoting (so literal `git reset HEAD~1` inside an `echo`
|
|
16
|
+
# or `grep` arg does NOT trigger). This script is a thin wrapper:
|
|
17
|
+
# fast-skip when "git" isn't in the command, otherwise dispatch to the
|
|
18
|
+
# helper and act on its JSON verdict.
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
22
|
+
if ! command -v cos_log_hook >/dev/null 2>&1; then cos_log_hook() { :; }; fi
|
|
23
|
+
|
|
24
|
+
# Fail-closed: a branch/HEAD-move guard that cannot read the command must DENY
|
|
25
|
+
# (observability-eye I8). python3 fallback keeps it working without jq.
|
|
26
|
+
cos_require_parser branch-guard
|
|
27
|
+
|
|
28
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
29
|
+
|
|
30
|
+
# Fast-path: every branch/HEAD-move this guard blocks is a `git` command. If
|
|
31
|
+
# the raw payload has no "git" substring at all there is nothing to deny —
|
|
32
|
+
# bail before any jq spawn (this gate fires on EVERY Bash command).
|
|
33
|
+
case "$INPUT" in
|
|
34
|
+
*git*) ;;
|
|
35
|
+
*) exit 0 ;;
|
|
36
|
+
esac
|
|
37
|
+
|
|
38
|
+
TOOL=$(printf '%s' "$INPUT" | cos_json_field tool_name)
|
|
39
|
+
if [[ "$TOOL" != "Bash" ]]; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# pr-mode is NOT a guard-kill. The command flows into branch_guard_check.py,
|
|
44
|
+
# which applies a positive pr-mode policy: allow agents/* branch + worktree-add,
|
|
45
|
+
# but still BLOCK HEAD-rewrites/commits on the shared integration checkout and
|
|
46
|
+
# pushes to protected branches. SPEC: docs/playbooks/pr-workflow.md § 5.
|
|
47
|
+
|
|
48
|
+
COMMAND=$(printf '%s' "$INPUT" | cos_json_field tool_input.command)
|
|
49
|
+
[[ -z "$COMMAND" ]] && exit 0
|
|
50
|
+
|
|
51
|
+
# Fast-skip: no "git" substring → no risk; skip the python startup cost.
|
|
52
|
+
if [[ "$COMMAND" != *git* ]]; then
|
|
53
|
+
exit 0
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
cos_log_hook branch-guard fire "tool=Bash"
|
|
57
|
+
|
|
58
|
+
# Resolve the helper through the file's physical location — works through
|
|
59
|
+
# the .claude/hooks/ symlinks that consumer projects install.
|
|
60
|
+
_src="${BASH_SOURCE[0]}"
|
|
61
|
+
while [ -L "$_src" ]; do
|
|
62
|
+
_dir="$(cd -P "$(dirname "$_src")" && pwd)"
|
|
63
|
+
_src="$(readlink "$_src")"
|
|
64
|
+
[[ "$_src" != /* ]] && _src="${_dir}/${_src}"
|
|
65
|
+
done
|
|
66
|
+
HOOKS_PHYS_DIR="$(cd -P "$(dirname "$_src")" && pwd)"
|
|
67
|
+
unset _src _dir
|
|
68
|
+
HELPER="${HOOKS_PHYS_DIR}/_helpers/branch_guard_check.py"
|
|
69
|
+
|
|
70
|
+
if [[ ! -f "$HELPER" ]]; then
|
|
71
|
+
# Fail-CLOSED: we are past the fast-skip, so the command IS git-related.
|
|
72
|
+
# A missing helper (dangling symlink / broken install) means we cannot
|
|
73
|
+
# verify it — deny rather than silently allow (observability-eye I8/A2).
|
|
74
|
+
cos_say error hook.branch_guard "branch-guard helper missing — failing closed on git command" 2>/dev/null || true
|
|
75
|
+
cos_log_hook branch-guard block "rule=helper-missing"
|
|
76
|
+
echo "BLOCKED: branch-guard helper missing ($HELPER) — cannot verify this git command; failing closed." >&2
|
|
77
|
+
echo " Restore src/core/hooks/_helpers/branch_guard_check.py (fail-closed: pr-mode does not bypass this guard)." >&2
|
|
78
|
+
exit 2
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Run the helper, capturing BOTH stdout (verdict) and stderr (crash detail).
|
|
82
|
+
# We are past the fast-skip, so the command IS git-related: a guard that
|
|
83
|
+
# cannot evaluate it must NOT silently allow (the old `2>/dev/null || allow`
|
|
84
|
+
# was a fail-OPEN security inversion — the guard silently stopped guarding,
|
|
85
|
+
# crash recorded nowhere). On helper failure we fail CLOSED and surface the
|
|
86
|
+
# crash to the eye. No non-git blast radius: non-git Bash exited at the fast-skip.
|
|
87
|
+
HELPER_ERR=$(mktemp)
|
|
88
|
+
HELPER_RC=0
|
|
89
|
+
VERDICT_JSON=$(printf '%s' "$INPUT" | python3 "$HELPER" 2>"$HELPER_ERR") || HELPER_RC=$?
|
|
90
|
+
HELPER_STDERR=$(cat "$HELPER_ERR" 2>/dev/null || true); rm -f "$HELPER_ERR"
|
|
91
|
+
|
|
92
|
+
if [[ "$HELPER_RC" -ne 0 || -z "$VERDICT_JSON" ]]; then
|
|
93
|
+
cos_say error hook.branch_guard "branch-guard helper failed (rc=${HELPER_RC}) — failing closed on git command" detail="${HELPER_STDERR:0:200}" 2>/dev/null || true
|
|
94
|
+
cos_log_hook branch-guard block "rule=helper-crash rc=${HELPER_RC}" || true
|
|
95
|
+
echo "BLOCKED: branch-guard helper failed (rc=${HELPER_RC}) — cannot verify this git command; failing closed." >&2
|
|
96
|
+
echo " Fix src/core/hooks/_helpers/branch_guard_check.py (fail-closed: pr-mode does not bypass this guard)." >&2
|
|
97
|
+
[[ -n "$HELPER_STDERR" ]] && echo " helper stderr: ${HELPER_STDERR}" >&2
|
|
98
|
+
exit 2
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
VERDICT=$(echo "$VERDICT_JSON" | jq -r '.verdict // "block"' 2>/dev/null || echo "block")
|
|
102
|
+
|
|
103
|
+
if [[ "$VERDICT" != "block" ]]; then
|
|
104
|
+
cos_log_hook branch-guard ok || true
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
REASON=$(echo "$VERDICT_JSON" | jq -r '.reason // "branch-guard-block"' 2>/dev/null)
|
|
109
|
+
MESSAGE=$(echo "$VERDICT_JSON" | jq -r '.message // ""' 2>/dev/null)
|
|
110
|
+
|
|
111
|
+
cos_log_hook branch-guard block "rule=${REASON}"
|
|
112
|
+
bash "$(dirname "$0")/../scripts/log-write.sh" \
|
|
113
|
+
--type "hook-block" --msg "branch-guard" --what "$REASON" 2>/dev/null || true
|
|
114
|
+
|
|
115
|
+
echo "WHY: trunk-based git keeps history linear and the blast radius reviewable — src/core/ edits reach every consumer via live symlinks." >&2
|
|
116
|
+
if [[ -n "$MESSAGE" ]]; then
|
|
117
|
+
printf '%s\n' "$MESSAGE" >&2
|
|
118
|
+
else
|
|
119
|
+
echo "BLOCKED: coding-os trunk-based git workflow forbids this command." >&2
|
|
120
|
+
echo " See src/core/rules/git-workflow.md (pr-mode applies a positive policy, not a bypass)." >&2
|
|
121
|
+
fi
|
|
122
|
+
exit 2
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse hook: fire-and-forget observation recording.
|
|
3
|
+
#
|
|
4
|
+
# Spawns capture.py in background for Write/Edit tools only. Must return
|
|
5
|
+
# in <1ms — all work happens in a background process. If capture.py
|
|
6
|
+
# itself fails (DB path broken, schema stale, import error), its stderr
|
|
7
|
+
# is redirected to $COS_STATE_DIR/.capture-errors.log so the Stop hook
|
|
8
|
+
# (check-capture-worked.sh) can surface the silent failure at session
|
|
9
|
+
# end instead of us losing observations invisibly for an entire session.
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
source "$(dirname "$0")/cos-env.sh" 2>/dev/null || true
|
|
13
|
+
if ! command -v cos_log_hook >/dev/null 2>&1; then cos_log_hook() { :; }; fi
|
|
14
|
+
|
|
15
|
+
INPUT="$(cos_read_stdin_bounded 2)"
|
|
16
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null || echo "")
|
|
17
|
+
|
|
18
|
+
COS_STATE_DIR="${COS_STATE_DIR:-.coding-os}"
|
|
19
|
+
|
|
20
|
+
# Heartbeat: prove the hook fires at all. If `cos hooks-log` shows no
|
|
21
|
+
# entries from this hook, Claude Code is not delivering the PostToolUse
|
|
22
|
+
# Write|Edit event (typically because .claude/settings.json changed
|
|
23
|
+
# mid-session — reload to pick up new hook config).
|
|
24
|
+
cos_log_hook capture-observation fire "tool=${TOOL_NAME}"
|
|
25
|
+
|
|
26
|
+
# Only capture Write, Edit, MultiEdit tool calls (skip Read, Glob, Grep, Bash).
|
|
27
|
+
# MultiEdit is the batched variant — Claude SDK emits it for most real agent
|
|
28
|
+
# edits, so excluding it produced ~0 observations (capture.py CAPTURE_TOOLS
|
|
29
|
+
# already includes MultiEdit; the shell filter was the stale layer).
|
|
30
|
+
case "$TOOL_NAME" in
|
|
31
|
+
Write|Edit|MultiEdit) ;;
|
|
32
|
+
*) exit 0 ;;
|
|
33
|
+
esac
|
|
34
|
+
|
|
35
|
+
# Resolve through the symlink before reaching ../thinking_os: $0 is the
|
|
36
|
+
# .claude/hooks/ symlink, so naive "$(dirname "$0")/../thinking_os" points
|
|
37
|
+
# at the non-existent .claude/thinking_os/ and capture.py was NEVER found —
|
|
38
|
+
# the hook logged "fire" then silently exited every time (the real
|
|
39
|
+
# root cause of observations=2). Sibling files like cos-env.sh work only
|
|
40
|
+
# because they ARE symlinked into .claude/hooks/; ../thinking_os/ is not.
|
|
41
|
+
_src="${BASH_SOURCE[0]:-$0}"
|
|
42
|
+
while [ -L "$_src" ]; do
|
|
43
|
+
_dir="$(cd -P "$(dirname "$_src")" && pwd)"
|
|
44
|
+
_src="$(readlink "$_src")"
|
|
45
|
+
[[ "$_src" != /* ]] && _src="$_dir/$_src"
|
|
46
|
+
done
|
|
47
|
+
HOOK_REAL_DIR="$(cd -P "$(dirname "$_src")" && pwd)"
|
|
48
|
+
unset _src _dir
|
|
49
|
+
CAPTURE_PY="${HOOK_REAL_DIR}/../thinking_os/capture.py"
|
|
50
|
+
if [ ! -f "$CAPTURE_PY" ]; then
|
|
51
|
+
cos_log_hook capture-observation skip "reason=capture_py_missing path=${CAPTURE_PY}" 2>/dev/null || true
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Ensure state dir exists for the error log (best-effort).
|
|
56
|
+
mkdir -p "$COS_STATE_DIR" 2>/dev/null || true
|
|
57
|
+
ERROR_LOG="$COS_STATE_DIR/.capture-errors.log"
|
|
58
|
+
|
|
59
|
+
# Run capture SYNCHRONOUSLY with embedding skipped. A backgrounded
|
|
60
|
+
# `(...) &` was reaped by the agent hook lifecycle before capture.py's
|
|
61
|
+
# INSERT+commit, so observations never persisted (6 inserts in
|
|
62
|
+
# 17 days despite the hook firing constantly). capture.py is ~one python
|
|
63
|
+
# startup under COS_CAPTURE_SKIP_EMBED; the FTS5 trigger indexes the row
|
|
64
|
+
# on INSERT so keyword recall works without the embedding. Real failures
|
|
65
|
+
# append a traceback to $ERROR_LOG for check-capture-worked.sh at Stop.
|
|
66
|
+
echo "$INPUT" | COS_CAPTURE_SKIP_EMBED=1 python3 "$CAPTURE_PY" 2>>"$ERROR_LOG" || true
|
|
67
|
+
|
|
68
|
+
# Visible signal — Claude Code does NOT render PostToolUse `systemMessage`
|
|
69
|
+
# directly in chat UI; route through the per-turn activity log so
|
|
70
|
+
# session-context.sh aggregates + emits on the next UserPromptSubmit
|
|
71
|
+
# (which IS rendered, mirroring the caveman pattern). systemMessage
|
|
72
|
+
# stays for future agent renderers + SDK consumers.
|
|
73
|
+
cos_record_activity memory "+obs" 2>/dev/null || true
|
|
74
|
+
printf '%s' '{"systemMessage":"[memory] +obs captured"}'
|
|
75
|
+
|
|
76
|
+
exit 0
|