Repository navigation
Repo true-up: Features own their state, augment official Features, host tasks fixed - #10
Closed
nabil-becker wants to merge 8 commits into
Closed
nabil-becker wants to merge 8 commits into
nabil-becker wants to merge 8 commits into
Conversation
Signed-off-by: Nabil Becker <nabil.becker@live.com>
…st tasks fixed Two consumer repos had to wrap this collection to get what they needed; this change folds those wrappers back in and sets the ecosystem rules. Features - claude-code: augments the official Anthropic Feature when present (install: auto/native/none), ships claude-host (resume one session by UUID via HOST_SESSION), owns CLAUDE_CONFIG_DIR in a named volume with a post-create hook. Fixes a set -u trap bug in the native installer. - git (new): worktree-aware wrapper that scopes GIT_DIR/GIT_WORK_TREE to the checkout (nested worktrees, temp folders, init/clone), post-create safe.directory and core.hooksPath, GIT_CONFIG_GLOBAL in a volume. - gh (new): verified release install when absent, GH_CONFIG_DIR volume, git credential helper from gh. - az (new): augments the official azure-cli Feature, AZURE_CONFIG_DIR volume, bicep from PATH. - common (new): dcf-persist, the shared helper behind every hook; vendored into the Features that use it, checked identical by lint. - coder-cli, argocd: own their login state the same way. - devcontainer-cli: --docker-path only for subcommands that take it. Host side (bootstrap) - devcontainer.yml: the Task 3.45 include env: bug fixed, so .env values reach the tasks (no dc:* passthrough needed; dc is an include alias); new pwsh, claude and homes tasks; in-container runs branch in the template because per-command if: is ignored. - devcontainer:homes (pwsh + bash twins) creates host folders for repos that bind-mount a Feature's state target to the host disk. - env_mnt removed everywhere: the checkout is the only thing on disk. Docs: README "How the pieces fit" (the paradigm), CONTRIBUTING conventions for augmentations, state ownership, vendored helpers and Taskfile pitfalls. CI matrices and the global scenario cover the new Features. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN Signed-off-by: Nabil Becker <nabil.becker@live.com>
…f the official claude The git hooks_and_safe_all scenario expected safe.directory * to be reported as added, but the Feature's own postCreateCommand adds it before the scenario runs, so kept is equally right. The claude-code augment_official scenario matched "node" in the path of the official Feature's claude, which the node Feature puts under /usr/local/share/nvm/ current/bin; match nvm or node and require it is not our native binary. Both passed in the wslc harness only because no hook ran there first. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN Signed-off-by: Nabil Becker <nabil.becker@live.com>
- .devcontainer/devcontainer.json references every src/<id> Feature as
./features/<id>; `task features:stage` copies them there (gitignored)
as initializeCommand, so unreleased changes are what runs here. The
checkout's git dir (outside OneDrive) is bind-mounted the way the
consumer repos do it, with the git Feature's wrapper scoping GIT_DIR.
- Host paths in every example use ${localEnv:USERPROFILE} only: on this
Windows host both USERPROFILE and HOME are set, so concatenating the
two doubled the path and failed the first start.
- gh-setup makes the global git config folder usable itself (dcf-persist)
instead of relying on the git hook having run first; installsAfter may
only name published Features (documented in CONTRIBUTING).
- post-create.sh reports what the Features set up instead of redoing it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN
Signed-off-by: Nabil Becker <nabil.becker@live.com>
…trapped with it The devhost Feature ports the housekeeping of the consumer repos into one installable piece: devhost-run-job with the scribe, secretary, librarian and tester backs (hook-driven, quiet notices, stakes, guards that undo a rewrite), devhost-briefing at session start, devhost-costs and the monthly cost report, devhost-adr, devhost-verify (ledger append-only and shape, secrets, forbidden words and redacted names, ADR shape, task descriptions, skill frontmatter) and devhost-init, which scaffolds a repo with LEXICON, PROCESS, TODO, the ledger and ADR folders, the four skills, the hook block and a CLAUDE.md include. Job state lives in the Feature's volume; every path and model is a DEVHOST_* / <JOB>_MODEL setting; no person is named, the person is "the Operator". Verified on Debian with a stub claude, and by 35 stdlib unit tests that now run in `task lint` and CI. This repository adopts it: devhost in its own devcontainer, the scaffold run inside it, CLAUDE.md written for the collection, the pre-commit guard, and a seeded TODO.md with what is next (merge or split PR #10, release, first sign-in and first back runs, consumers' adoption). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN Signed-off-by: Nabil Becker <nabil.becker@live.com>
CI's shellcheck reports SC2317 (unreachable) for job_claude and redact, which the sourced job file calls; the host's 0.11 does not. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN Signed-off-by: Nabil Becker <nabil.becker@live.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN Signed-off-by: Nabil Becker <nabil.becker@live.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN Signed-off-by: Nabil Becker <nabil.becker@live.com>
6 of 8 tasks
nabil-becker
added a commit
that referenced
this pull request
Oct 16, 2026
## What The Features half of the repo true-up, landed before the rest so it can be released and the true-up can pin released versions. - **New Features:** `git`, `gh`, `az`, `common`, `devhost`, `kube-state` (owns `KUBECONFIG` state, the way `gh`/`az` own theirs). - **Changed:** `claude-code`, `dsc` (verifies the tarball without api.github.com: pinned digests, then the release page; never installs unverified), `velero`, `argocd`, `coder-cli`, `devcontainer-cli`. - **devhost:** one source of `DEVHOST_*` defaults; a non-identifying engineer handle (`DEVHOST_ENGINEER`, default `operator`); verify refuses a tracked `.env`; descriptive slug ids for backlog items. - **Tasks:** `task test` / `test:global` stop with a clear message when no Docker daemon answers (CI is the test loop). Built by path-filtering `repo-true-up` (#10) and today's work: only `src/`, `test/`, `.github/workflows/`, `.gitignore`, and the Feature parts of README, CONTRIBUTING and the Taskfile. Every commit keeps its original author and sign-off. The devhost of this repo, bootstrap, `.githooks`, and the way-of-working records stay in #10 for later. ## Why Backlog: `kube-state-feature`, `one-devhost-defaults`, `dsc-without-github-api`, `workstation-feature-tests`, and `release-collection` (this PR is what gets released). Consumers cannot pull `git`/`gh`/`az`/`common`/`devhost` until they are published. ## Checklist - [x] Every commit is signed off (DCO): checked, every sign-off matches its author - [x] `version` bumped in `src/<id>/devcontainer-feature.json` (semver) - [x] Downloads remain checksum-verified; nothing unverified is piped into a shell - [ ] `install.sh` is idempotent and does not assume a `remoteUser`: review - [ ] Tests updated and `task test FEATURE=<id>` passes: **not run locally (no Docker in the devhost); CI is the first real run** - [x] `taskfile.yml` present and registered via `installTaskfile` (new Features) - [x] `task lint` passes - [x] `NOTES.md` updated, `task docs` run (no diff) **Reviewer notes:** the README "How the pieces fit" section was trimmed to the Feature parts by an agent, so check its wording. `devhost` is at 1.1.0 although it was never published; reset to 1.0.0 before the release if you prefer. Agent co-author trailers use `@noreply.invalid` addresses on purpose (ADR 0002). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Nabil Becker <nabil.becker@live.com> Signed-off-by: devhost agent <devhost-agent@noreply.invalid> Co-authored-by: Claude Fable 5.1 <claude-fable-5-1@noreply.invalid> Co-authored-by: devhost agent <devhost-agent@noreply.invalid> Co-authored-by: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid> Co-authored-by: Claude Haiku 4.5 <claude-haiku-4-5@noreply.invalid> Co-authored-by: Claude Opus 5.5 <claude-opus-5-5@noreply.invalid>
nabil-becker
added a commit
that referenced
this pull request
Oct 19, 2026
…trapped with it The devhost Feature ports the housekeeping of the consumer repos into one installable piece: devhost-run-job with the scribe, secretary, librarian and tester backs (hook-driven, quiet notices, stakes, guards that undo a rewrite), devhost-briefing at session start, devhost-costs and the monthly cost report, devhost-adr, devhost-verify (ledger append-only and shape, secrets, forbidden words and redacted names, ADR shape, task descriptions, skill frontmatter) and devhost-init, which scaffolds a repo with LEXICON, PROCESS, TODO, the ledger and ADR folders, the four skills, the hook block and a CLAUDE.md include. Job state lives in the Feature's volume; every path and model is a DEVHOST_* / <JOB>_MODEL setting; no person is named, the person is "the Operator". Verified on Debian with a stub claude, and by 35 stdlib unit tests that now run in `task lint` and CI. This repository adopts it: devhost in its own devcontainer, the scaffold run inside it, CLAUDE.md written for the collection, the pre-commit guard, and a seeded TODO.md with what is next (merge or split PR #10, release, first sign-in and first back runs, consumers' adoption). Co-Authored-By: Claude Fable 5.1 <claude-fable-5-1@noreply.invalid> Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN Signed-off-by: Nabil Becker <nabil.becker@live.com> Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The collection becomes an ecosystem: every Feature with state owns it (named volume + post-create hook), augmentation Features sit after the official ones instead of replacing them (
claude-code, newgit,gh,az), a sharedcommonhelper (dcf-persist) backs every hook, and the vendored host tasks get the fixes two consumer repos had to work around (.envvalues reaching the include,pwsh/claude/homestasks,--docker-pathonly where accepted).env_mntis gone; the checkout is the only thing on disk.Why
Two repos (the office and DSNP) had started wrapping the collection locally: a
dc:*passthrough for the Task 3.45 dotenv bug, aclaude-hostlauncher, host-side folder creation for Claude's home, a git wrapper for worktrees underGIT_DIR, chowns of config dirs. Those are now upstream, generically, and the rules are written down in README "How the pieces fit" and CONTRIBUTING. One deliberate decision: nodependsOnon the official Anthropic Feature (npm-only, unpinned, unverified); ours augments it when listed and installs the verified native binary otherwise.Verified on real Debian containers via
wslcfor every Feature touched (install as root, tests as non-root, hooks twice, state persisting across containers, volume/bind/image detection on real mounts). Two bugs found and fixed on the way (set -utrap in the claude-code installer;--docker-pathpassed tofeatures generate-docs).Checklist
Signed-off-by:, DCO) - automatic aftertask repo:setupversionbumped insrc/<id>/devcontainer-feature.json(semver)install.shis idempotent and does not assume aremoteUsertest/<id>/test.sh,scenarios.json) andtask test FEATURE=<id>passes (in this repo's devcontainer or on Linux/macOS) - run as equivalentwslcDebian runs; CI runs the real harnesstaskfile.ymlpresent and registered viainstallTaskfile(new Features)task lintpassesNOTES.mdupdated if behaviour or options changed, andtask docsrun sosrc/<id>/README.mdis currentNot included:
.devcontainer/devcontainer-lock.json(stale, from an experiment; left untracked). The repo's own devcontainer enablesgitandghonly after the first release publishes them.🤖 Generated with Claude Code
https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN