diff --git a/.rabbit/README.md b/.rabbit/README.md new file mode 100644 index 0000000..34aa0ed --- /dev/null +++ b/.rabbit/README.md @@ -0,0 +1,7 @@ +# Rabbit Context + +This directory keeps Rabbit-facing repo context and generated `dev.kit` evidence. + +- `context.yaml` is generated by `dev.kit repo`; do not edit it manually. +- Keep human-authored Rabbit CI notes, delivery entry points, and repo-specific workflow guidance in this README. +- After changing repo docs, manifests, scripts, or workflows, run `dev.kit repo` to refresh generated context. diff --git a/.rabbit/context.yaml b/.rabbit/context.yaml index da34818..0e7b86d 100644 --- a/.rabbit/context.yaml +++ b/.rabbit/context.yaml @@ -5,8 +5,8 @@ version: udx.dev/dev.kit/v1 generator: tool: dev.kit repo: https://github.com/udx/dev.kit - version: 0.20.0 - generated_at: 2026-07-08T15:15:15Z + version: 0.20.1 + generated_at: 2026-07-10T09:48:47Z sources: homepage: https://udx.dev/kit repository: https://github.com/udx/dev.kit diff --git a/README.md b/README.md index 73ff837..116cc0e 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,15 @@ -`dev.kit` turns repositories into self-explaining repo contracts for humans, scripts, and CI/CD. +`dev.kit` provides repo context coverage for every handoff. + +It reads repo-owned docs, manifests, workflows, commands, dependencies, and gaps, then writes `.rabbit/context.yaml` so humans, agents, scripts, and CI/CD systems such as Rabbit CI can work from the same declared contract. It helps teams and repositories: 1. understand how the repo actually works 2. keep repo standards, manifests, refs, and dependency contracts traceable -3. regenerate reliable context from repo signals instead of tribal knowledge +3. regenerate reliable handoff context from repo signals instead of tribal knowledge The model is: diff --git a/changes.md b/changes.md index 4043d1e..6c824ca 100644 --- a/changes.md +++ b/changes.md @@ -1,5 +1,10 @@ # Changes +### 0.20.1 + +- Keep declared root YAML contract discovery aligned with repo file filtering so gitignored local/private YAML is not promoted into generated context. +- Seed missing `.rabbit/README.md` files so repos initialized by `dev.kit repo` have a clear Rabbit-facing notes surface without adding a generic `docs/README.md` stub. + ### 0.20.0 - Discover root YAML config contracts from explicit top-level `contract` / `contracts` metadata or typed `kind` + `version` manifests instead of filename-specific allowlists. diff --git a/docs/how-it-works.md b/docs/how-it-works.md index 30cf2ca..63c6239 100644 --- a/docs/how-it-works.md +++ b/docs/how-it-works.md @@ -1,6 +1,6 @@ # How It Works -`dev.kit` turns repo-declared structure into a working repo contract. +`dev.kit` turns repo-declared structure into context coverage for repo handoffs. The default starting point is: diff --git a/lib/modules/repo_scaffold.sh b/lib/modules/repo_scaffold.sh index 0da8c25..b2f50ab 100644 --- a/lib/modules/repo_scaffold.sh +++ b/lib/modules/repo_scaffold.sh @@ -26,6 +26,15 @@ This repository uses \`dev.kit\` for repo-driven context coverage. - Run \`dev.kit\` to inspect environment and repo context status - Run \`dev.kit repo\` to regenerate \`.rabbit/context.yaml\` +" + + dev_kit_repo_write_if_missing "${repo_root}/.rabbit/README.md" "# Rabbit Context + +This directory keeps Rabbit-facing repo context and generated \`dev.kit\` evidence. + +- \`context.yaml\` is generated by \`dev.kit repo\`; do not edit it manually. +- Keep human-authored Rabbit CI notes, delivery entry points, and repo-specific workflow guidance in this README. +- After changing repo docs, manifests, scripts, or workflows, run \`dev.kit repo\` to refresh generated context. " dev_kit_repo_write_if_missing "${repo_root}/.github/dependabot.yml" "version: 2 @@ -293,9 +302,21 @@ EOF dev_kit_repo_declared_root_contract_manifest_files() { local repo_root="$1" + local candidate_files="" local manifest_path="" local manifest_rel="" + if dev_kit_sync_has_git_repo "$repo_root"; then + candidate_files="$( + ( + cd "$repo_root" && + git ls-files -z --cached --others --exclude-standard -- '*.yaml' '*.yml' 2>/dev/null + ) | tr '\0' '\n' | awk -v repo_root="$repo_root" 'NF && $0 !~ /\// && $0 !~ /^\./ { printf "%s/%s\n", repo_root, $0 }' | sort + )" + else + candidate_files="$(find "$repo_root" -maxdepth 1 -type f \( -name '*.yaml' -o -name '*.yml' \) 2>/dev/null | sort)" + fi + while IFS= read -r manifest_path; do [ -f "$manifest_path" ] || continue manifest_rel="${manifest_path#"${repo_root}/"}" @@ -310,7 +331,7 @@ dev_kit_repo_declared_root_contract_manifest_files() { printf '%s\n' "$manifest_rel" fi done </dev/null | sort) +$candidate_files EOF } diff --git a/package-lock.json b/package-lock.json index 5a5a785..7e95bda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@udx/dev-kit", - "version": "0.20.0", + "version": "0.20.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@udx/dev-kit", - "version": "0.20.0", + "version": "0.20.1", "license": "MIT", "bin": { "dev-kit": "bin/dev-kit", diff --git a/package.json b/package.json index 5c1b774..49af2ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@udx/dev-kit", - "version": "0.20.0", + "version": "0.20.1", "description": "Context-driven engineering toolkit for AI agents and developers", "license": "MIT", "repository": { diff --git a/tests/suite.sh b/tests/suite.sh index 53164b7..666e675 100644 --- a/tests/suite.sh +++ b/tests/suite.sh @@ -12,12 +12,14 @@ DOCUMENTED_SHELL_REPO="$REPO_DIR/tests/fixtures/documented-shell-repo" DOCKER_REPO="$REPO_DIR/tests/fixtures/docker-repo" SIMPLE_ACTION_REPO="$TEST_HOME/simple-action-repo" HOME_ACTION_REPO="$TEST_HOME/home-action-repo" +DOCUMENTED_SHELL_ACTION_REPO="$TEST_HOME/documented-shell-action-repo" DOCKER_ACTION_REPO="$TEST_HOME/docker-action-repo" EMPTY_REPO="$TEST_HOME/empty-repo" IGNORED_ACTION_REPO="$TEST_HOME/ignored-action-repo" WORKFLOW_CONTRACT_REPO="$TEST_HOME/workflow-contract-repo" DECLARED_CONFIG_REPO="$TEST_HOME/declared-config-repo" REFERENCE_DOC_COMMAND_REPO="$TEST_HOME/reference-doc-command-repo" +PRESERVED_RABBIT_REPO="$TEST_HOME/preserved-rabbit-repo" AVAILABLE_TEST_GROUPS="core repo-contract" TEST_ONLY="${DEV_KIT_TEST_ONLY:-}" @@ -115,6 +117,9 @@ setup_declared_config_repo() { # Declared Config Repo Runtime variables are declared in `work-conf.yaml`. +EOF + cat > "$repo_dir/.gitignore" <<'EOF' +local-private.yaml EOF cat > "$repo_dir/work-conf.yaml" <<'EOF' --- @@ -134,6 +139,13 @@ contract: purpose: local automation interface notes refs: - README.md +EOF + cat > "$repo_dir/local-private.yaml" <<'EOF' +--- +kind: localPrivateConfig +version: example.dev/private-v1/config +config: + env: {} EOF cat > "$repo_dir/source-notes.yaml" <<'EOF' # Source notes with references are useful context, but not a manifest contract. @@ -235,6 +247,7 @@ if should_run_explicit "repo-contract"; then declared_config_dependencies="$(awk '/^dependencies:/{flag=1;next} /^# /{if(flag) exit} flag{print}' "$declared_config_context_yaml")" assert_contains "$declared_config_dependencies" "repo: example/runtime" "repo contract: traces declared root YAML manifest owner as dependency" assert_not_contains "$(cat "$declared_config_context_yaml")" "path: source-notes.yaml" "repo contract: does not promote source comments alone to manifest" + assert_not_contains "$(cat "$declared_config_context_yaml")" "path: local-private.yaml" "repo contract: excludes gitignored root YAML contracts" fi if should_run "core"; then @@ -382,7 +395,9 @@ if should_run "core"; then assert_contains "$env_json" "\"command\": \"env\"" "env: reports command name" assert_contains "$env_json" "\"workflow\": {" "env: reports workflow contract" - repo_json="$(cd "$DOCUMENTED_SHELL_REPO" && dev.kit repo --json)" + cp -R "$DOCUMENTED_SHELL_REPO" "$DOCUMENTED_SHELL_ACTION_REPO" + + repo_json="$(cd "$DOCUMENTED_SHELL_ACTION_REPO" && dev.kit repo --json)" assert_contains "$repo_json" "\"archetype\":" "repo: reports archetype" assert_contains "$repo_json" "\"context\":" "repo: reports context path" assert_contains "$repo_json" "\"context_status\": \"current\"" "repo: reports current workflow context after write" @@ -391,7 +406,7 @@ if should_run "core"; then assert_contains "$repo_json" "\"id\": \"confirm-research-fix-loop\"" "repo: includes confirmation loop action" assert_contains "$repo_json" "\"workflow\": {" "repo: reports workflow contract" - repo_text="$(cd "$DOCUMENTED_SHELL_REPO" && dev.kit repo)" + repo_text="$(cd "$DOCUMENTED_SHELL_ACTION_REPO" && dev.kit repo)" assert_contains "$repo_text" "[workflow]" "repo text: renders workflow section" assert_contains "$repo_text" "[read first]" "repo text: renders read first section" assert_contains "$repo_text" "[factors]" "repo text: renders factors section" @@ -407,7 +422,7 @@ if should_run "core"; then printf 'boom\n' >&2 return 42 } - dev_kit_cmd_repo text "$DOCUMENTED_SHELL_REPO" 2>&1 + dev_kit_cmd_repo text "$DOCUMENTED_SHELL_ACTION_REPO" 2>&1 )" repo_write_failure_status=$? set -e @@ -504,6 +519,7 @@ EOF declared_config_dependencies="$(awk '/^dependencies:/{flag=1;next} /^# /{if(flag) exit} flag{print}' "$declared_config_context_yaml")" assert_contains "$declared_config_dependencies" "repo: example/runtime" "declared config repo: traces explicit root YAML manifest owner as dependency" assert_not_contains "$(cat "$declared_config_context_yaml")" "path: source-notes.yaml" "declared config repo: does not promote source comments alone to manifest" + assert_not_contains "$(cat "$declared_config_context_yaml")" "path: local-private.yaml" "declared config repo: excludes gitignored root YAML contracts" mkdir -p "$WORKFLOW_CONTRACT_REPO/.github/workflows" git -C "$WORKFLOW_CONTRACT_REPO" init >/dev/null 2>&1 @@ -558,6 +574,22 @@ EOF assert_not_contains "$(cat "$reference_doc_context_yaml")" "run: make build" "reference docs repo: ignores reference-only build example" assert_not_contains "$(cat "$reference_doc_context_yaml")" "run: make run" "reference docs repo: ignores reference-only run example" + mkdir -p "$PRESERVED_RABBIT_REPO/.rabbit" "$PRESERVED_RABBIT_REPO/docs" + git -C "$PRESERVED_RABBIT_REPO" init >/dev/null 2>&1 + cat > "$PRESERVED_RABBIT_REPO/README.md" <<'EOF' +# Preserved Rabbit Docs Repo +EOF + cat > "$PRESERVED_RABBIT_REPO/.rabbit/README.md" <<'EOF' +# Existing Rabbit Notes + +Keep this repo-specific Rabbit CI guidance. +EOF + preserved_rabbit_json="$(cd "$PRESERVED_RABBIT_REPO" && dev.kit repo --json)" + assert_contains "$preserved_rabbit_json" "\"context\":" "preserved rabbit repo: reports context path" + assert_contains "$(cat "$PRESERVED_RABBIT_REPO/.rabbit/README.md")" "Existing Rabbit Notes" "preserved rabbit repo: keeps existing rabbit README" + assert_not_contains "$(cat "$PRESERVED_RABBIT_REPO/.rabbit/README.md")" "This directory keeps Rabbit-facing repo context" "preserved rabbit repo: does not overwrite rabbit README" + assert_file_missing "$PRESERVED_RABBIT_REPO/docs/README.md" "preserved rabbit repo: does not create generic docs README" + mkdir -p "$EMPTY_REPO" git -C "$EMPTY_REPO" init >/dev/null 2>&1 @@ -573,11 +605,15 @@ EOF assert_file_exists "$EMPTY_REPO/README.md" "empty repo: creates README" assert_file_exists "$EMPTY_REPO/docs" "empty repo: creates docs dir" + assert_file_missing "$EMPTY_REPO/docs/README.md" "empty repo: does not create generic docs README" assert_file_exists "$EMPTY_REPO/.rabbit" "empty repo: creates rabbit dir" + assert_file_exists "$EMPTY_REPO/.rabbit/README.md" "empty repo: creates rabbit README" assert_file_exists "$EMPTY_REPO/.github/workflows" "empty repo: creates workflows dir" assert_file_exists "$EMPTY_REPO/.github/dependabot.yml" "empty repo: creates dependabot config" assert_contains "$(cat "$EMPTY_REPO/.github/dependabot.yml")" "package-ecosystem: github-actions" "empty repo: dependabot targets github actions" assert_contains "$(cat "$EMPTY_REPO/README.md")" "This repository uses \`dev.kit\`" "empty repo: seeds README" + assert_contains "$(cat "$EMPTY_REPO/.rabbit/README.md")" "Rabbit-facing repo context" "empty repo: seeds rabbit README" + assert_contains "$(cat "$EMPTY_REPO/.rabbit/README.md")" "\`context.yaml\` is generated by \`dev.kit repo\`" "empty repo: explains generated context" fi printf "ok - dev.kit suite completed\n"