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,343 @@
|
|
|
1
|
+
# JWT for Service-to-Service — Implementation Reference
|
|
2
|
+
|
|
3
|
+
The hexagonal Go backend mints short-lived JWTs to authenticate calls to the FastAPI AI adapter. This file is the canonical implementation pattern.
|
|
4
|
+
|
|
5
|
+
## Token Shape
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"alg": "EdDSA",
|
|
10
|
+
"typ": "JWT",
|
|
11
|
+
"kid": "2026-04"
|
|
12
|
+
}.{
|
|
13
|
+
"iss": "https://business-api.app.com",
|
|
14
|
+
"aud": "ai-adapter",
|
|
15
|
+
"sub": "usr_8h2k4n9d3p7q",
|
|
16
|
+
"iat": 1745678901,
|
|
17
|
+
"exp": 1745679201,
|
|
18
|
+
"nbf": 1745678871,
|
|
19
|
+
"jti": "550e8400-e29b-41d4-a716-446655440000",
|
|
20
|
+
"scope": ["ai:chat", "ai:recommend"],
|
|
21
|
+
"tenant_id": "tnt_abc123"
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Claim | Required | Purpose |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `iss` | yes | Issuer URL (must match `/.well-known/jwks.json` host). |
|
|
28
|
+
| `aud` | yes | Intended audience — verifier rejects if not its own ID. |
|
|
29
|
+
| `sub` | yes | Subject (user ID). |
|
|
30
|
+
| `iat` | yes | Issued at (Unix epoch seconds). |
|
|
31
|
+
| `exp` | yes | Expires at (Unix epoch seconds). 5-15 min for service tokens. |
|
|
32
|
+
| `nbf` | recommended | Not-before — defends against issued-in-future replay; allow ~30s clock skew. |
|
|
33
|
+
| `jti` | recommended | Unique ID — pin in a replay-tracking blocklist if you need exactly-once semantics. |
|
|
34
|
+
| `scope` | optional | Whitespace- or array-separated permissions. |
|
|
35
|
+
| `tenant_id`, custom | optional | Multi-tenant routing / RLS hints. |
|
|
36
|
+
|
|
37
|
+
## Algorithm Choice
|
|
38
|
+
|
|
39
|
+
| Algorithm | Verdict | Notes |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| **EdDSA (Ed25519)** | ✅ default | Fast, small keys, no parameter footguns. RFC 8032. |
|
|
42
|
+
| **ES256 (P-256)** | ✅ alternative | Widely supported in browsers/WebAuthn. |
|
|
43
|
+
| **RS256 (RSA-SHA256)** | ✅ if EdDSA unavailable | Larger keys (2048+), slower. |
|
|
44
|
+
| **HS256** | ⚠️ symmetric only | Use only when verifier == issuer. NEVER share the secret across teams. |
|
|
45
|
+
| **`alg: none`** | ❌ never | Library MUST reject. Switch libraries if yours doesn't. |
|
|
46
|
+
| **PS256** | ✅ if you need RSA-PSS | Modern padding; pick over RS256 when both are available. |
|
|
47
|
+
|
|
48
|
+
## Key Management
|
|
49
|
+
|
|
50
|
+
### Generate Keys (offline, once per rotation)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Ed25519
|
|
54
|
+
openssl genpkey -algorithm Ed25519 -out priv-2026-04.pem
|
|
55
|
+
openssl pkey -in priv-2026-04.pem -pubout -out pub-2026-04.pem
|
|
56
|
+
|
|
57
|
+
# Then convert pub key to JWK format and add to your JWKS:
|
|
58
|
+
# { "kty": "OKP", "crv": "Ed25519", "x": "...", "kid": "2026-04", "alg": "EdDSA", "use": "sig" }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Storage
|
|
62
|
+
|
|
63
|
+
- **Private key** — sealed in a secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, K8s sealed-secrets). NEVER in env vars in plaintext, NEVER in source.
|
|
64
|
+
- **Public keys** — published at `https://<issuer>/.well-known/jwks.json`. Include current + previous `kid` for the lifetime of the longest-lived token.
|
|
65
|
+
|
|
66
|
+
### JWKS Endpoint
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
# FastAPI side, just for completeness — usually the issuer publishes this.
|
|
70
|
+
@router.get("/.well-known/jwks.json")
|
|
71
|
+
async def jwks():
|
|
72
|
+
return {
|
|
73
|
+
"keys": [
|
|
74
|
+
{
|
|
75
|
+
"kty": "OKP",
|
|
76
|
+
"crv": "Ed25519",
|
|
77
|
+
"x": current_pub_jwk_x,
|
|
78
|
+
"kid": "2026-04",
|
|
79
|
+
"alg": "EdDSA",
|
|
80
|
+
"use": "sig",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"kty": "OKP",
|
|
84
|
+
"crv": "Ed25519",
|
|
85
|
+
"x": prev_pub_jwk_x,
|
|
86
|
+
"kid": "2026-03",
|
|
87
|
+
"alg": "EdDSA",
|
|
88
|
+
"use": "sig",
|
|
89
|
+
},
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Cache headers: `Cache-Control: public, max-age=600` (10 min). Verifiers should refresh on `kid` miss.
|
|
95
|
+
|
|
96
|
+
### Rotation Cadence
|
|
97
|
+
|
|
98
|
+
- Quarterly under normal operation.
|
|
99
|
+
- Immediately on suspected compromise (or any access by someone who shouldn't have it).
|
|
100
|
+
- Process:
|
|
101
|
+
1. Generate new keypair, give it `kid = YYYY-MM`.
|
|
102
|
+
2. Publish in JWKS alongside current.
|
|
103
|
+
3. Wait for verifier caches to refresh (10 min).
|
|
104
|
+
4. Switch issuer to mint with new `kid`.
|
|
105
|
+
5. Continue publishing old `kid` until longest token expires.
|
|
106
|
+
6. Remove old key from JWKS + secrets manager.
|
|
107
|
+
|
|
108
|
+
## Mint (Go Issuer)
|
|
109
|
+
|
|
110
|
+
```go
|
|
111
|
+
package serviceauth
|
|
112
|
+
|
|
113
|
+
import (
|
|
114
|
+
"crypto/ed25519"
|
|
115
|
+
"time"
|
|
116
|
+
|
|
117
|
+
"github.com/golang-jwt/jwt/v5"
|
|
118
|
+
"github.com/google/uuid"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
type Issuer struct {
|
|
122
|
+
privKey ed25519.PrivateKey
|
|
123
|
+
kid string
|
|
124
|
+
issuer string
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
type ServiceClaims struct {
|
|
128
|
+
Scope []string `json:"scope"`
|
|
129
|
+
TenantID string `json:"tenant_id,omitempty"`
|
|
130
|
+
jwt.RegisteredClaims
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
func New(privKey ed25519.PrivateKey, kid, issuer string) *Issuer {
|
|
134
|
+
return &Issuer{privKey: privKey, kid: kid, issuer: issuer}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
func (i *Issuer) Mint(audience, userID, tenantID string, scopes []string, ttl time.Duration) (string, error) {
|
|
138
|
+
now := time.Now()
|
|
139
|
+
claims := ServiceClaims{
|
|
140
|
+
Scope: scopes,
|
|
141
|
+
TenantID: tenantID,
|
|
142
|
+
RegisteredClaims: jwt.RegisteredClaims{
|
|
143
|
+
Subject: userID,
|
|
144
|
+
Issuer: i.issuer,
|
|
145
|
+
Audience: jwt.ClaimStrings{audience},
|
|
146
|
+
IssuedAt: jwt.NewNumericDate(now),
|
|
147
|
+
ExpiresAt: jwt.NewNumericDate(now.Add(ttl)),
|
|
148
|
+
NotBefore: jwt.NewNumericDate(now.Add(-30 * time.Second)),
|
|
149
|
+
ID: uuid.NewString(),
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
tok := jwt.NewWithClaims(jwt.SigningMethodEdDSA, claims)
|
|
153
|
+
tok.Header["kid"] = i.kid
|
|
154
|
+
return tok.SignedString(i.privKey)
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Usage:
|
|
159
|
+
|
|
160
|
+
```go
|
|
161
|
+
token, err := serviceTokens.Mint(
|
|
162
|
+
"ai-adapter", // aud
|
|
163
|
+
user.ID, // sub
|
|
164
|
+
user.TenantID, // optional
|
|
165
|
+
[]string{"ai:chat"},
|
|
166
|
+
5 * time.Minute, // ttl
|
|
167
|
+
)
|
|
168
|
+
req.Header.Set("Authorization", "Bearer " + token)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Verify (Python Verifier)
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
import asyncio
|
|
175
|
+
import time
|
|
176
|
+
|
|
177
|
+
import httpx
|
|
178
|
+
import jwt
|
|
179
|
+
from cachetools import TTLCache
|
|
180
|
+
|
|
181
|
+
JWKS_CACHE: TTLCache[str, dict] = TTLCache(maxsize=4, ttl=600)
|
|
182
|
+
JWKS_LOCK = asyncio.Lock()
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
async def get_jwks(issuer: str, force_refresh: bool = False) -> dict:
|
|
186
|
+
if not force_refresh and issuer in JWKS_CACHE:
|
|
187
|
+
return JWKS_CACHE[issuer]
|
|
188
|
+
async with JWKS_LOCK:
|
|
189
|
+
if not force_refresh and issuer in JWKS_CACHE:
|
|
190
|
+
return JWKS_CACHE[issuer]
|
|
191
|
+
async with httpx.AsyncClient(timeout=5) as client:
|
|
192
|
+
resp = await client.get(f"{issuer}/.well-known/jwks.json")
|
|
193
|
+
resp.raise_for_status()
|
|
194
|
+
jwks = resp.json()
|
|
195
|
+
JWKS_CACHE[issuer] = jwks
|
|
196
|
+
return jwks
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
async def verify_service_token(
|
|
200
|
+
token: str,
|
|
201
|
+
*,
|
|
202
|
+
expected_issuer: str,
|
|
203
|
+
expected_audience: str,
|
|
204
|
+
) -> dict:
|
|
205
|
+
"""Verify a service-to-service JWT and return its claims.
|
|
206
|
+
|
|
207
|
+
Raises jwt.InvalidTokenError on any failure. NEVER fall back to
|
|
208
|
+
accepting an invalid token — log and reject.
|
|
209
|
+
"""
|
|
210
|
+
unverified_header = jwt.get_unverified_header(token)
|
|
211
|
+
kid = unverified_header.get("kid")
|
|
212
|
+
if not kid:
|
|
213
|
+
raise jwt.InvalidTokenError("missing kid header")
|
|
214
|
+
|
|
215
|
+
jwks = await get_jwks(expected_issuer)
|
|
216
|
+
key_jwk = next((k for k in jwks["keys"] if k["kid"] == kid), None)
|
|
217
|
+
if key_jwk is None:
|
|
218
|
+
# Rotation just happened? refresh once.
|
|
219
|
+
jwks = await get_jwks(expected_issuer, force_refresh=True)
|
|
220
|
+
key_jwk = next((k for k in jwks["keys"] if k["kid"] == kid), None)
|
|
221
|
+
if key_jwk is None:
|
|
222
|
+
raise jwt.InvalidTokenError(f"unknown kid {kid}")
|
|
223
|
+
|
|
224
|
+
if key_jwk.get("alg") != "EdDSA":
|
|
225
|
+
raise jwt.InvalidTokenError("unexpected key alg")
|
|
226
|
+
|
|
227
|
+
public_key = jwt.algorithms.OKPAlgorithm.from_jwk(key_jwk)
|
|
228
|
+
|
|
229
|
+
payload = jwt.decode(
|
|
230
|
+
token,
|
|
231
|
+
public_key,
|
|
232
|
+
algorithms=["EdDSA"],
|
|
233
|
+
audience=expected_audience,
|
|
234
|
+
issuer=expected_issuer,
|
|
235
|
+
leeway=30, # clock skew tolerance
|
|
236
|
+
options={
|
|
237
|
+
"require": ["sub", "iat", "exp", "aud", "iss", "nbf"],
|
|
238
|
+
"verify_iat": True,
|
|
239
|
+
"verify_exp": True,
|
|
240
|
+
"verify_nbf": True,
|
|
241
|
+
"verify_aud": True,
|
|
242
|
+
"verify_iss": True,
|
|
243
|
+
},
|
|
244
|
+
)
|
|
245
|
+
return payload
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### FastAPI Integration
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
from fastapi import Depends, Header, HTTPException
|
|
252
|
+
|
|
253
|
+
async def require_service_token(
|
|
254
|
+
authorization: str = Header(...),
|
|
255
|
+
) -> dict:
|
|
256
|
+
if not authorization.startswith("Bearer "):
|
|
257
|
+
raise HTTPException(401, "invalid_authorization_header")
|
|
258
|
+
token = authorization[7:]
|
|
259
|
+
try:
|
|
260
|
+
return await verify_service_token(
|
|
261
|
+
token,
|
|
262
|
+
expected_issuer="https://business-api.app.com",
|
|
263
|
+
expected_audience="ai-adapter",
|
|
264
|
+
)
|
|
265
|
+
except jwt.InvalidTokenError as exc:
|
|
266
|
+
# NEVER leak exc detail back to the caller — log it.
|
|
267
|
+
logger.warning("service token rejected", extra={"error": str(exc)})
|
|
268
|
+
raise HTTPException(401, "invalid_token") from exc
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def require_scope(scope: str):
|
|
272
|
+
async def _check(claims: dict = Depends(require_service_token)) -> dict:
|
|
273
|
+
if scope not in claims.get("scope", []):
|
|
274
|
+
raise HTTPException(403, "missing_scope")
|
|
275
|
+
return claims
|
|
276
|
+
return _check
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
@router.post("/conversations/{cid}/messages")
|
|
280
|
+
async def send_message(
|
|
281
|
+
cid: str,
|
|
282
|
+
body: SendMessageRequest,
|
|
283
|
+
claims: dict = Depends(require_scope("ai:chat")),
|
|
284
|
+
):
|
|
285
|
+
user_id = claims["sub"]
|
|
286
|
+
# ... use user_id in the use case ...
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Replay Defense
|
|
290
|
+
|
|
291
|
+
Service JWTs with 5-minute TTL + clock skew leeway = effectively 6 minutes of replay window. For sensitive operations, also track `jti`:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
# In-memory or Redis blocklist of recently-seen jti values.
|
|
295
|
+
SEEN_JTI: TTLCache[str, bool] = TTLCache(maxsize=10_000, ttl=600)
|
|
296
|
+
|
|
297
|
+
async def verify_with_jti_check(token: str, ...) -> dict:
|
|
298
|
+
payload = await verify_service_token(token, ...)
|
|
299
|
+
jti = payload["jti"]
|
|
300
|
+
if jti in SEEN_JTI:
|
|
301
|
+
raise jwt.InvalidTokenError("replay")
|
|
302
|
+
SEEN_JTI[jti] = True
|
|
303
|
+
return payload
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
For multi-instance deployments, back this with Redis SET NX EX.
|
|
307
|
+
|
|
308
|
+
## Error Handling — Generic Outward, Specific in Logs
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
# WRONG — leaks reason to attacker
|
|
312
|
+
raise HTTPException(401, f"jwt error: {exc}")
|
|
313
|
+
|
|
314
|
+
# RIGHT — opaque to client, full detail in logs.
|
|
315
|
+
logger.warning("service token rejected", extra={
|
|
316
|
+
"error_class": type(exc).__name__,
|
|
317
|
+
"error_message": str(exc),
|
|
318
|
+
"request_id": request_id,
|
|
319
|
+
})
|
|
320
|
+
raise HTTPException(401, detail="invalid_token")
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Common JWT Mistakes
|
|
324
|
+
|
|
325
|
+
1. **Accepting `alg: none`** — library bug; switch.
|
|
326
|
+
2. **Trusting `alg` from token header** without algorithm allowlist — accept only specific algs you expect.
|
|
327
|
+
3. **Verifying signature but not `aud`/`iss`** — token from one service accepted by another.
|
|
328
|
+
4. **No `exp` enforcement** — token valid forever.
|
|
329
|
+
5. **No clock skew leeway** — minor NTP drift causes 5% failure rate.
|
|
330
|
+
6. **Storing JWT secret next to code** — first leaked secret.
|
|
331
|
+
7. **HS256 across teams** — shared secret = no trust boundary.
|
|
332
|
+
8. **JWT in URL** — leaks via referrer / logs / browser history.
|
|
333
|
+
9. **Long TTL "to reduce DB load"** — every minute = N more minutes a stolen token is valid.
|
|
334
|
+
10. **No JWKS caching** — verifier hits issuer on every request.
|
|
335
|
+
|
|
336
|
+
## Source Material
|
|
337
|
+
|
|
338
|
+
- *RFC 7519* — JWT.
|
|
339
|
+
- *RFC 7517* — JWK / JWKS.
|
|
340
|
+
- *RFC 8725* — JWT Best Current Practices (the must-read).
|
|
341
|
+
- *Auth0 — JWT Handbook* (PDF, free).
|
|
342
|
+
- *OWASP JWT Cheat Sheet*.
|
|
343
|
+
- `golang-jwt/jwt v5` (Go), `PyJWT` (Python), `jose` (Node) — current libs.
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Passkeys + 2FA — Implementation Patterns
|
|
2
|
+
|
|
3
|
+
The two strong-auth methods worth implementing in 2026. Passkeys are the new default; TOTP 2FA is the universal fallback.
|
|
4
|
+
|
|
5
|
+
## Passkeys (WebAuthn / FIDO2)
|
|
6
|
+
|
|
7
|
+
A passkey is an asymmetric keypair bound to a (user, relying-party) pair. The private key never leaves the user's device (or its synced password manager — iCloud Keychain, Google Password Manager, 1Password). The server only stores the public key.
|
|
8
|
+
|
|
9
|
+
Phishing-proof: the browser/OS verifies the relying-party origin before signing. A fake site can't trick the device into producing a valid signature.
|
|
10
|
+
|
|
11
|
+
### Database Schema
|
|
12
|
+
|
|
13
|
+
```sql
|
|
14
|
+
CREATE TABLE passkey_credentials (
|
|
15
|
+
credential_id BYTEA PRIMARY KEY, -- WebAuthn credential id (raw bytes)
|
|
16
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
17
|
+
public_key BYTEA NOT NULL, -- COSE-encoded key
|
|
18
|
+
sign_count BIGINT NOT NULL DEFAULT 0, -- replay defense (some authenticators)
|
|
19
|
+
transports TEXT[] NOT NULL DEFAULT '{}', -- "internal", "hybrid", "usb", "nfc", "ble"
|
|
20
|
+
aaguid UUID, -- authenticator make/model
|
|
21
|
+
backup_eligible BOOLEAN NOT NULL DEFAULT false,
|
|
22
|
+
backup_state BOOLEAN NOT NULL DEFAULT false,
|
|
23
|
+
nickname TEXT, -- user-given name ("MacBook", "iPhone")
|
|
24
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
25
|
+
last_used_at TIMESTAMPTZ
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX idx_passkey_user ON passkey_credentials(user_id);
|
|
29
|
+
|
|
30
|
+
-- Per-flow challenge storage (short-lived):
|
|
31
|
+
CREATE TABLE webauthn_challenges (
|
|
32
|
+
challenge BYTEA PRIMARY KEY,
|
|
33
|
+
user_id TEXT NOT NULL,
|
|
34
|
+
purpose TEXT NOT NULL CHECK (purpose IN ('register', 'authenticate')),
|
|
35
|
+
expires_at TIMESTAMPTZ NOT NULL,
|
|
36
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
37
|
+
);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Registration Flow
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
1. Client: POST /auth/passkey/register/begin
|
|
44
|
+
Body: { user_id } (user already authenticated via existing method)
|
|
45
|
+
|
|
46
|
+
2. Server:
|
|
47
|
+
- Generate random 32-byte challenge
|
|
48
|
+
- Store in webauthn_challenges with purpose='register', exp=NOW()+5min
|
|
49
|
+
- Return:
|
|
50
|
+
{
|
|
51
|
+
rp: { id: "app.com", name: "My App" },
|
|
52
|
+
user: { id: <random user-handle>, name: "user@example.com", displayName: "Name" },
|
|
53
|
+
challenge: <b64url>,
|
|
54
|
+
pubKeyCredParams: [
|
|
55
|
+
{ type: "public-key", alg: -7 }, // ES256
|
|
56
|
+
{ type: "public-key", alg: -8 }, // EdDSA
|
|
57
|
+
{ type: "public-key", alg: -257 }, // RS256
|
|
58
|
+
],
|
|
59
|
+
authenticatorSelection: {
|
|
60
|
+
residentKey: "preferred",
|
|
61
|
+
userVerification: "preferred",
|
|
62
|
+
},
|
|
63
|
+
attestation: "none", // skip attestation unless you have a reason
|
|
64
|
+
timeout: 60000,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
3. Client (browser/RN): navigator.credentials.create({ publicKey: ... })
|
|
68
|
+
On RN: use react-native-passkey (Expo) or expo-secure-store-based bridge.
|
|
69
|
+
|
|
70
|
+
4. Server: POST /auth/passkey/register/finish
|
|
71
|
+
Body: { credential, transports }
|
|
72
|
+
|
|
73
|
+
5. Server validates:
|
|
74
|
+
- Lookup challenge, verify not expired, mark used.
|
|
75
|
+
- Verify clientDataJSON.type === "webauthn.create"
|
|
76
|
+
- Verify clientDataJSON.challenge matches
|
|
77
|
+
- Verify clientDataJSON.origin === expected origin
|
|
78
|
+
- Verify rpIdHash inside attestationObject matches SHA-256("app.com")
|
|
79
|
+
- Extract + store public key + credential id + transports + flags.
|
|
80
|
+
|
|
81
|
+
Use simplewebauthn (Node) / py_webauthn (Python) / go-webauthn (Go).
|
|
82
|
+
Never roll your own.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Authentication Flow
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
1. Client: POST /auth/passkey/authenticate/begin
|
|
89
|
+
Body: { user_identifier?: "user@example.com" } // optional — true username-less is supported
|
|
90
|
+
|
|
91
|
+
2. Server:
|
|
92
|
+
- Lookup user (if identifier provided)
|
|
93
|
+
- Get list of registered credential IDs for this user
|
|
94
|
+
- Generate challenge, store with purpose='authenticate', exp=NOW()+5min
|
|
95
|
+
- Return:
|
|
96
|
+
{
|
|
97
|
+
challenge: <b64url>,
|
|
98
|
+
rpId: "app.com",
|
|
99
|
+
allowCredentials: [
|
|
100
|
+
{ type: "public-key", id: <cred_id>, transports: [...] },
|
|
101
|
+
...
|
|
102
|
+
],
|
|
103
|
+
userVerification: "preferred",
|
|
104
|
+
timeout: 60000,
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
3. Client: navigator.credentials.get({ publicKey: ... })
|
|
108
|
+
|
|
109
|
+
4. Server: POST /auth/passkey/authenticate/finish
|
|
110
|
+
Body: { assertion }
|
|
111
|
+
|
|
112
|
+
5. Server:
|
|
113
|
+
- Lookup credential by id
|
|
114
|
+
- Verify signature using stored public key against (clientDataJSON || authenticatorData)
|
|
115
|
+
- Verify challenge, origin, rpId hash
|
|
116
|
+
- Verify userPresent flag (always required); userVerified if you require strong auth
|
|
117
|
+
- If sign_count > 0 in stored, verify new signCount > stored (replay defense)
|
|
118
|
+
- Update last_used_at, sign_count
|
|
119
|
+
- Issue session token → return as in any sign-in flow.
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Production Tips
|
|
123
|
+
|
|
124
|
+
- **Display name + nickname** for each credential — users with multiple devices need to know which to deregister.
|
|
125
|
+
- **At least 2 passkeys per account** before allowing the user to disable password — single credential = single point of lockout.
|
|
126
|
+
- **Re-auth required** to add or remove a passkey (fresh-session ≤5 min OR password re-prompt).
|
|
127
|
+
- **Don't use attestation** unless you actually have a policy that needs it (e.g., enterprise device-bound). Most consumer apps: `attestation: "none"`.
|
|
128
|
+
- **`backupEligible` / `backupState`** flags tell you whether the credential is sync'd via iCloud/Google. Synced credentials = lower lockout risk; consider skipping the "add a 2nd passkey" prompt for them.
|
|
129
|
+
- **TOTP fallback** for users who can't / won't use passkeys. NEVER passwords-only.
|
|
130
|
+
|
|
131
|
+
### Client Library Choices
|
|
132
|
+
|
|
133
|
+
- **Web** — browser native (`navigator.credentials`), wrapped by `simplewebauthn/browser`.
|
|
134
|
+
- **React Native (Expo)** — `expo-passkey` or `react-native-passkey`. Both call into native APIs (ASAuthorization on iOS, CredentialManager on Android 14+).
|
|
135
|
+
- **React Native (bare)** — `react-native-passkey` or DIY native module using AuthenticationServices (iOS) and Credential Manager (Android).
|
|
136
|
+
|
|
137
|
+
Both platforms require **associated domains** setup:
|
|
138
|
+
|
|
139
|
+
- iOS: `apple-app-site-association` file at `https://app.com/.well-known/apple-app-site-association`.
|
|
140
|
+
- Android: `assetlinks.json` at `https://app.com/.well-known/assetlinks.json`.
|
|
141
|
+
|
|
142
|
+
Without these, the OS refuses to bind passkeys to your origin.
|
|
143
|
+
|
|
144
|
+
## TOTP 2FA — Universal Fallback
|
|
145
|
+
|
|
146
|
+
For users who can't (or won't) use passkeys. RFC 6238.
|
|
147
|
+
|
|
148
|
+
### Schema
|
|
149
|
+
|
|
150
|
+
```sql
|
|
151
|
+
CREATE TABLE totp_secrets (
|
|
152
|
+
user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
153
|
+
secret_encrypted BYTEA NOT NULL, -- envelope encrypted via KMS
|
|
154
|
+
enrolled_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
155
|
+
last_used_at TIMESTAMPTZ
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
CREATE TABLE totp_backup_codes (
|
|
159
|
+
id BIGSERIAL PRIMARY KEY,
|
|
160
|
+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
161
|
+
code_hash TEXT NOT NULL, -- Argon2id hash
|
|
162
|
+
used_at TIMESTAMPTZ, -- NULL = unused
|
|
163
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
CREATE INDEX idx_backup_codes_user_unused
|
|
167
|
+
ON totp_backup_codes(user_id) WHERE used_at IS NULL;
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Enrollment
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
import secrets
|
|
174
|
+
import base64
|
|
175
|
+
import pyotp
|
|
176
|
+
from cryptography.fernet import Fernet # or your KMS wrapper
|
|
177
|
+
|
|
178
|
+
def begin_totp_enrollment(user, account_email):
|
|
179
|
+
secret = pyotp.random_base32() # 32 chars, 160-bit entropy
|
|
180
|
+
encrypted = kms_encrypt(secret.encode()) # envelope encrypt
|
|
181
|
+
# Store as PENDING — only commit on first valid verification
|
|
182
|
+
pending_store.put(user.id, encrypted, ttl_seconds=600)
|
|
183
|
+
uri = pyotp.TOTP(secret).provisioning_uri(
|
|
184
|
+
name=account_email, issuer_name="MyApp",
|
|
185
|
+
)
|
|
186
|
+
return {"uri": uri, "qr_payload": uri} # render QR on client
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def confirm_totp_enrollment(user, code):
|
|
190
|
+
encrypted = pending_store.get(user.id)
|
|
191
|
+
if not encrypted: raise EnrollmentExpired
|
|
192
|
+
secret = kms_decrypt(encrypted).decode()
|
|
193
|
+
if not pyotp.TOTP(secret).verify(code, valid_window=1):
|
|
194
|
+
raise InvalidCode
|
|
195
|
+
db.execute("INSERT INTO totp_secrets (user_id, secret_encrypted) VALUES ($1, $2)",
|
|
196
|
+
user.id, encrypted)
|
|
197
|
+
pending_store.delete(user.id)
|
|
198
|
+
return generate_backup_codes(user)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Verification
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
def verify_totp(user, code):
|
|
205
|
+
encrypted = db.fetch_one("SELECT secret_encrypted FROM totp_secrets WHERE user_id = $1", user.id)
|
|
206
|
+
if not encrypted: return False
|
|
207
|
+
secret = kms_decrypt(encrypted["secret_encrypted"]).decode()
|
|
208
|
+
return pyotp.TOTP(secret).verify(code, valid_window=1) # ±30s
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Rate limit: 5 attempts per 5 minutes per user. Lock account on 10 failed attempts in 15 minutes (with admin/email recovery).
|
|
212
|
+
|
|
213
|
+
### Backup Codes
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
import argon2
|
|
217
|
+
|
|
218
|
+
def generate_backup_codes(user, n=10):
|
|
219
|
+
plaintext = [secrets.token_urlsafe(8).replace("_", "").replace("-", "").upper()[:8] for _ in range(n)]
|
|
220
|
+
ph = argon2.PasswordHasher()
|
|
221
|
+
rows = [(user.id, ph.hash(code)) for code in plaintext]
|
|
222
|
+
db.execute_many("INSERT INTO totp_backup_codes (user_id, code_hash) VALUES ($1, $2)", rows)
|
|
223
|
+
return plaintext # show ONCE; user MUST save
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def consume_backup_code(user, code):
|
|
227
|
+
rows = db.fetch_all(
|
|
228
|
+
"SELECT id, code_hash FROM totp_backup_codes WHERE user_id = $1 AND used_at IS NULL",
|
|
229
|
+
user.id,
|
|
230
|
+
)
|
|
231
|
+
ph = argon2.PasswordHasher()
|
|
232
|
+
for row in rows:
|
|
233
|
+
try:
|
|
234
|
+
ph.verify(row["code_hash"], code)
|
|
235
|
+
db.execute("UPDATE totp_backup_codes SET used_at = NOW() WHERE id = $1", row["id"])
|
|
236
|
+
return True
|
|
237
|
+
except argon2.exceptions.VerifyMismatchError:
|
|
238
|
+
continue
|
|
239
|
+
return False
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Format: 8-character base32-like alphanumeric (e.g., `K8FH2NQR`). Easy to type, hard to brute force, distinct from real codes.
|
|
243
|
+
|
|
244
|
+
### Recovery
|
|
245
|
+
|
|
246
|
+
If user loses both phone (no TOTP) and backup codes:
|
|
247
|
+
|
|
248
|
+
1. They contact support.
|
|
249
|
+
2. Identity verified out-of-band (KYC, gov ID, manager approval, etc.) — DO NOT make this easy.
|
|
250
|
+
3. Support agent triggers a 24-48 hour cooling-off period during which the account is frozen.
|
|
251
|
+
4. After the cool-off, a unique recovery link is emailed.
|
|
252
|
+
5. User completes recovery; ALL sessions and devices revoked; ALL credentials reset.
|
|
253
|
+
|
|
254
|
+
This is where attackers attack. The cool-off + out-of-band check is the single most important defense.
|
|
255
|
+
|
|
256
|
+
## When to Skip 2FA
|
|
257
|
+
|
|
258
|
+
- Don't skip for: any account with payment, PII, or write access to shared resources.
|
|
259
|
+
- DO skip the prompt for: low-value accounts where forcing 2FA would crater conversion (early product). Offer it as opt-in.
|
|
260
|
+
- Once enabled, 2FA cannot be silently disabled — always require fresh-session + email confirmation.
|
|
261
|
+
|
|
262
|
+
## Step-Up Authentication
|
|
263
|
+
|
|
264
|
+
Some operations need stronger auth than the session provides (e.g., transferring money, deleting account, disabling 2FA):
|
|
265
|
+
|
|
266
|
+
- Re-prompt for password OR passkey OR TOTP.
|
|
267
|
+
- Mark the session as "fresh" with a timestamp.
|
|
268
|
+
- Operation requires `fresh_at > NOW() - INTERVAL '5 min'`.
|
|
269
|
+
- After the operation, fresh marker decays.
|
|
270
|
+
|
|
271
|
+
```sql
|
|
272
|
+
ALTER TABLE sessions ADD COLUMN fresh_until TIMESTAMPTZ;
|
|
273
|
+
|
|
274
|
+
-- When user re-authenticates for a sensitive op:
|
|
275
|
+
UPDATE sessions SET fresh_until = NOW() + INTERVAL '5 minutes' WHERE id = $1;
|
|
276
|
+
|
|
277
|
+
-- Sensitive endpoint guard:
|
|
278
|
+
SELECT 1 FROM sessions WHERE id = $1 AND fresh_until > NOW();
|
|
279
|
+
-- → 0 rows → 401, prompt for re-auth
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Source Material
|
|
283
|
+
|
|
284
|
+
- *FIDO Alliance — Passkey UX Guidelines* (current, updated 2025).
|
|
285
|
+
- *WebAuthn Level 3* spec (W3C 2024 candidate recommendation).
|
|
286
|
+
- *RFC 6238* — TOTP.
|
|
287
|
+
- *OWASP Authentication Cheat Sheet*.
|
|
288
|
+
- *RFC 9800* — Passkey-related threat model (2024 draft).
|
|
289
|
+
- `simplewebauthn` (TS), `py_webauthn` (Python), `go-webauthn` (Go) — battle-tested libs.
|