Skip to content

Features/true up features - #11

Merged
nabil-becker merged 16 commits into
mainfrom
features/true-up-features
Oct 16, 2026
Merged

nabil-becker merged 16 commits into
mainfrom
features/true-up-features

Conversation

@nabil-becker

@nabil-becker nabil-becker commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

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

  • Every commit is signed off (DCO): checked, every sign-off matches its author
  • version bumped in src/<id>/devcontainer-feature.json (semver)
  • 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
  • taskfile.yml present and registered via installTaskfile (new Features)
  • task lint passes
  • 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

nabil-becker and others added 16 commits October 15, 2026 12:28
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 <claude-fable-5-1@noreply.invalid>
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 <claude-fable-5-1@noreply.invalid>
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 <claude-fable-5-1@noreply.invalid>
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 <claude-fable-5-1@noreply.invalid>
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 <claude-fable-5-1@noreply.invalid>
Claude-Session: https://claude.ai/code/session_01FBCVdVNMWSkF3PKnDH1UFN
Signed-off-by: Nabil Becker <nabil.becker@live.com>
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>
…py (one-devhost-defaults)

redact.py now imports devhost_common (redact_text); a test fails if a second
common module or a repeated default returns. devhost 1.0.1.

Co-Authored-By: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
…files

The engineer handle is DEVHOST_ENGINEER as a slug, else operator; it is no
longer derived from the git user name, since it is committed. .gitignore
gains .env, .env.* and !.env.example, and verify.py refuses tracked .env
files (with a test). devhost 1.0.2.

Co-Authored-By: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
…ub-api)

Digests come from the sha256 option, a pinned digests.txt, or the release
page on github.com; api.github.com is no longer called, so the CI rate limit
cannot fail the install. Bump to 1.1.0.

Co-Authored-By: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
…ature)

New Feature kube-state: KUBECONFIG in a named volume
(kube-state-config-${devcontainerId}) on /var/lib/devcontainer-features/kube-state,
the kube-state-setup post-create hook, kube-state:* tasks, tests, README and
CI matrix entries. Installs no kubectl; orders after kubectl-helm-minikube.

Co-Authored-By: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
…disk block (workstation-feature-tests, bootstrap-host-disk-docs)

Co-Authored-By: Claude Haiku 4.5 <claude-haiku-4-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
The secretary picks a two-to-four-word kebab-case slug naming the item, unique in the file, never reused, never renamed, instead of the next TD-nn number. Template, brief, night-shift report shape, NOTES and tests follow; the devhost Feature goes to 1.1.0.

Co-Authored-By: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
…what this tree holds

Brings in only the Feature-related text of README.md and CONTRIBUTING.md
(Feature table rows, the ecosystem rules for Features, augmentation and
state conventions, Feature folder layout), and removes from the tasks, the
lint workflow and .gitignore what points at paths that arrive with the repo
true-up: the features:stage task, the bootstrap/host/*.sh shellcheck glob
and the ignore lines for .devcontainer/features and the devhost redact list.

Co-Authored-By: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
The scenario calls task through the Taskfile but never installed the
go-task Feature, so task was not found.

Co-Authored-By: Claude Sonnet 5.5 <claude-sonnet-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
…plates

The close-session skill and CLAUDE.devhost.md templates name the
@noreply.invalid form; noreply@anthropic.com links to a stranger's
GitHub account (ADR 0002 in devcontainer-features).

Co-Authored-By: Claude Opus 5.5 <claude-opus-5-5@noreply.invalid>
Signed-off-by: devhost agent <devhost-agent@noreply.invalid>
awood1076
awood1076 previously approved these changes Oct 16, 2026
@nabil-becker
nabil-becker dismissed awood1076’s stale review October 16, 2026 02:28

Updated permissions

@nabil-becker
nabil-becker merged commit d16a536 into main Oct 16, 2026
69 checks passed
@nabil-becker
nabil-becker deleted the features/true-up-features branch October 16, 2026 03:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants