Skip to content

Init agent skills for Tirith - #361

Open
Akshat0694 wants to merge 13 commits into
mainfrom
f/agent-skills
Open

Init agent skills for Tirith#361
Akshat0694 wants to merge 13 commits into
mainfrom
f/agent-skills

Conversation

@Akshat0694

Copy link
Copy Markdown
Member

Description

  • What changes are being made?

    • Un-hides the Skills page (/tirith/skills/). It was excluded from the build by a
      pages.exclude entry in docusaurus.config.js, with the navbar item commented out
      beside its original. Both are restored, and Skills is added to the shared colophon
      between Learn and Docs.
    • Corrects four claims on the page that had gone stale while it was hidden. The page
      was written before several accuracy passes landed on the rest of the site, so it was
      the last surface still asserting things that are not true:
      • "Run tirith lint, read the report" and "tirith lint reads the engine's own
        registries"
        tirith lint is not in the released package. src/tirith/cli.py
        dispatches platform and ui and nothing else. Now describes the trap classes and
        notes that tirith ui validates against the live registries today.
      • "the extra timeout exit code"ExitStatus.ERROR_TIMEOUT = 2 is declared in
        status.py and returned nowhere, including on the platform path, which maps a
        timeout to 1.
      • "VS Code tasks that lint and evaluate in one keystroke, and a pre-commit hook"
        both need files that are not in this repository and both drive tirith lint. That
        entry now points at the pipeline reference, which does ship, and says the editor loop
        is in development.
    • Removes 12 em dashes from the page's copy. It was hidden when that convention was
      applied to the rest of the site, so it never got the pass. The shipped page now has
      none.
    • Instruments the install copy control with the existing skillCopy event. Copying
      the skill pack is this page's primary action and it was the only untracked one.
    • Tidies two comments that documented the hiding and are now wrong: the pages.exclude
      block, and the note in Colophon.js explaining why Skills was absent from the footer.
  • Why are these changes necessary?

    • The page was hidden because it advertised a skill pack that did not exist in this
      repository, so its curl commands and every file link returned 404. That was fixed
      when .claude/skills/tirith-policies/ was ported in Docs/promote landing pages #288, so the reason for hiding it
      is gone. All ten reference/*.md files it links to now resolve.
    • Restoring it unchanged would have shipped four claims the rest of the site has already
      corrected. A page telling a reader to run a command that does not exist is worse than a
      missing page: it fails after they have committed to trying.
  • Which issues or tickets does this PR close or relate to?

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Documentation update
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Other (please specify):

Checklist

  • Code has been linted.
    npm run build passes. onBrokenLinks: 'throw' is what proves every internal link
    resolves. No Python changed, so black --check . is unaffected.
  • Documentation has been updated (if needed).
    documentation/README.md: the /tirith/skills/ row is un-struck and the paragraph
    explaining how to restore the hidden page is removed.
  • Tests have been added or updated (if needed).
    No test changes. This is documentation-site copy and configuration; nothing touches
    src/tirith/. Correctness is enforced by the build itself, which throws on a broken
    internal link.
  • Any breaking changes have been communicated to the team.
    None. One route is added; nothing is removed or renamed.

Screenshots or Recordings (if applicable)

Additional Information

Build warning, pre-existing and benign. The build reports a broken anchor,
/tirith/skills → /tirith/learn/#playground. It is a false positive: id="playground" is
present in the rendered /learn/ HTML, but Docusaurus only indexes anchors it can extract
from Markdown headings, not id attributes on JSX elements. The warning disappeared while
this page was excluded and returns with it. It does not fail the build.

Verified rather than assumed:

  • All 10 reference/*.md files the page links to exist under
    .claude/skills/tirith-policies/.
  • The shipped /skills/index.html contains none of the four corrected claims, and zero
    em dashes.
  • Navbar and colophon both render the Skills link on other pages.

One thing a reviewer should look at. The page still describes the skill pack as the
source of truth for policy authoring. That is true, and the pack was itself corrected in a
recent pass, but the two now have to be kept in step: if tirith lint ships, this page,
reference/validate.md and reference/pipelines.md all change together.

@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Akshat0694 and others added 6 commits September 4, 2026 00:22
- Updated CSS for verification lines to improve layout and readability.
- Introduced a new DocBreadcrumbsWrapper component to integrate CopyPageMenu with breadcrumbs.
- Added styles for the new DocBreadcrumbsWrapper component.
- Refactored PaginatorNavLink to use a reusable Arrow component for navigation arrows.
- Updated installation instructions in multiple documentation files to specify versioning for Tirith.
- Added a new agent skills documentation file detailing the installation and usage of the Tirith skill pack.
- Enhanced CI integration documentation to clarify usage and improve instructions.
- Created a skill.sh script for installing the Tirith policy skill, ensuring a clean and safe installation process.
The skill's core instruction is "run the policy against a plan that should fail it",
but the pack pointed at src/tirith/tui/examples/, which does not exist in a project
that installed via skill.sh. examples/required-tags/ now ships with the pack: the
SKILL.md policy, a plan that fails it (exit 3) and one that passes (exit 0). skill.sh
downloads it alongside the markdown; all four exits in its README were run.

Exit 2 was described three ways, all stale: "declared in status.py but never returned"
(SKILL.md, Cursor rule), "platform check timeout" (verdicts.md, platform.md). status.py
no longer declares it, and a platform timeout raises CheckError, which exits 1. The
pack now says 2 is argparse's usage error and Tirith has no timeout code.

The `tirith lint` warning was explained in full in SKILL.md, schema.md and validate.md,
each with its own roadmap speculation. validate.md is now the one place; the others
are a sentence and a pointer. The "When lint ships" section is gone: a skill should
describe the present, and three copies of a forecast go wrong together.

SKILL.md is restructured around lists rather than paragraphs, with the same facts.
…rith

A separate skill rather than a reference inside tirith-policies, because the shape is the same
for every source language (inventory, classify, translate, verify, report) and only the mapping
tables differ. Sentinel is the first; Checkov and Rego slot in as further reference files.

The mapping is measured, not guessed. All 110 policies in hashicorp/terraform-sentinel-policies
and the CIS AWS policy set were classified: 41 translate exactly, 40 approximately, 29 not at
all. The full table ships as reference/sentinel-corpus.md so an agent can look a public policy
up instead of re-deriving it. The two dominant losses are per-block conjunction (issue #316)
and instance-level pairing across resources; tfconfig-only policies account for most of the
cloud-agnostic set.

Five worked examples, one per fidelity story, each verified against the engine. Approximate
translations ship diverges.json, a plan where Sentinel and Tirith disagree, because a fidelity
note nobody can run is a fidelity note nobody reads. Three engine behaviours the translation
tables depend on were verified rather than assumed: Contains on a map tests keys; a
present-but-null attribute is evaluated, not skipped; and the action operation emits one result
per action, so a destroy guard does not fire on a replacement.

skill.sh installs both skills unconditionally. All downloads still complete before anything is
copied into place, so a failed fetch of either pack installs neither.
… skill test

A second Claude session installed both skills over the network, wrote three policies from
plain-English requirements and reported what it found. Each finding was reproduced against
the engine before being fixed.

- terraform-plan.md's action example used "destroy"; plan JSON says "delete". Copied
  literally, the guard exits 0 on a real delete. The section is rewritten around the fact
  that `action` emits one result per action element: `NotEquals "delete"` blocks deletes and
  replacements, `ContainedIn ["delete"]` with `!` blocks only a pure delete, and the order of
  a replacement's two actions cannot be tested.
- The migrate example prevent-database-destroy moves from approximate to exact using the
  universal form; its divergence plan becomes a second failing plan. sentinel.md and two
  corpus rows are corrected the same way; one row had put a list into NotEquals, which
  never equals an action string and passes everything.
- A type-scoped policy on a plan with none of that type exits 3 by default and 1 with
  error_tolerance 1; there is no "nothing in scope, pass". Documented in verdicts.md and as a
  trap in SKILL.md. verdicts.md's exit table no longer claims 0 for that case, and
  debug-ci.md no longer sends the reader there.
- The docs page said "no restart"; a running session did not see the newly installed skills
  until restarted. Qualified.
The live test's third phase migrated a four-policy Sentinel set and found that the skill's own
restrict-ssh-ingress example returns no verdict when the plan also holds a security group with
no ingress blocks: the tolerated skip erases the bastion's failure (issue #293). Both skills now
say that the error_tolerance-2 "where the attribute exists" idiom is unsafe on mixed plans until
#293 is fixed, and the plan reference recommends one evaluator per type over a wildcard with
tolerance.

Also from that phase: an unset optional list renders as null in plan JSON and Contains or
NotContains on null is a hard unsupported-type failure that no tolerance forgives, so the
`x else default` idiom row is split; scope differs even for exact rows because Sentinel's
find_resources excludes no-op and deleted resources; an approximation that drops the test a
param fed must name the orphaned param rather than ship an unread variables.json; and the
mock-to-fixture recipe now says to read the test .hcl for the expected verdict first.
AkashS0510 and others added 6 commits September 4, 2026 17:05
…elper table

A fresh session auto-discovered both skills, ran fourteen fixtures and probes with every exit
code as predicted, and checked the text against the engine. Three claims were wrong or half
right:

- An unknown condition.type does exit 3 with `errors` empty, but its result message names the
  evaluator. The skill said it was indistinguishable from a real violation, which sent the reader
  to the plan instead of to the message. Six passages corrected.
- Exit 2 is never returned. The CLI catches argparse's SystemExit and exits 1, so a bad argument
  or `tirith lint` is 1, not 2. The morning's correction had replaced one wrong story about exit
  2 with another.
- `tirith --version` is mentioned in install.md but not where the install command is given.

The Sentinel helper table now says its fidelity column rates the test only: scope and a computed
attribute can still make a translation approximate. The smoke test's migration of an
allowed-regions policy on aws_s3_bucket was exactly that case, since `region` is usually
inherited from the provider and absent from change.after.
…tation

- Introduced Terraform plan provider with lessons covering resource attributes, actions, and counts.
- Added Kubernetes provider with lessons on manifest handling and attribute paths.
- Updated the lessons structure to support multiple providers and their respective lessons.
- Enhanced the learn page to display lessons grouped by provider, improving navigation.
- Updated styles for track headers to maintain consistency across the documentation.
- Expanded provider overview documentation to include guidance on creating new providers and examples of potential use cases.
PR #365 changed the roll-up so a tolerated skip no longer erases a sibling's verdict. Both skills
now state the fixed behaviour where they used to warn about the bug, and the SSH example's notes
say a skipped group leaves the bastion's failure standing. Re-verified: the probe plan that
masked the bastion before now exits 3, and a compliant bucket next to a destroyed one exits 0.
@sonarqubecloud

sonarqubecloud Bot commented Sep 4, 2026

Copy link
Copy Markdown

❌ The last analysis has failed.

See analysis details on SonarQube Cloud

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